Spring日常笔记记录10--动态代理实现InvocationHandler

动态代理

动态代理是指,程序在整个运行构成中根本就不存在目标类的代理类,目标对象的代理对象只是由代理生成工具(不是真实定义的类)在程序运行时由JVM根据反射等机制动态生成的。代理对象与目标对象的代理关系在程序运行时才确立。

 

一、JDK动态代理

动态代理的实现方式常用的有两种:使用JDK的Proxy,与通过CGLIB生成代理。jdk的动态要求目标对象必须实现接口,这是Java设计上的要求。

从jdk1.3以来,Java语言通过java.lang.reflect包提供三个支持代理模式Proxy,Method和InvocationHandler。

 

二、JDK动态代理实现步骤:

1.创建目录类,SomeServiceImpl目标类,给它的doSome,doOther增加输出时间和事务。

Spring日常笔记记录10--动态代理实现InvocationHandler

 

 Spring日常笔记记录10--动态代理实现InvocationHandler

 

 Spring日常笔记记录10--动态代理实现InvocationHandler

 

 

2.创建InvocHandler接口的实现类,在这个类实现给目标方法增加功能。

package com.hlc.handler;

import com.hlc.util.ServiceTools;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {
    //目标对象
    private  Object target; //SomeServiceImpl类

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //通过代理对象执行时,会调用执行invoke()
        Object res = null;
        ServiceTools.doLog();
        //执行目标类的方法,通过Method类实现
        res = method.invoke(target,args);  //SomeServiceImpl , doOther() , doSome()
        ServiceTools.doTrans();
        //目标方法的执行结果
        return res;
    }
}

 

3.使用jdk中类Proxy,创建代理对象。实现创建对象的能力。

package com.hlc;

import com.hlc.handler.MyInvocationHandler;
import com.hlc.service.SomeService;
import com.hlc.service.impl.SomeServiceImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class MyApp {
    public static void main(String[] args) {
        //使用jdk的Proxy创建代理对象
        //创建目标对象
        SomeService target = new SomeServiceImpl();

        //使用InvocationHandler对象
        InvocationHandler handler = new MyInvocationHandler(target);

        //使用Proxy创建代理
        SomeService proxy = (SomeService) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),handler
        );

        //通过代理执行方法,会调用handler中的invoke()
        proxy.doSome();
    }
}

运行结果:

执行了MyInvocationHandler中的involved
非业务方法,方法的执行时间:Mon Jul 26 00:25:49 CST 2021
执行业务方法doSome
方法执行完毕后,提交事务

 

 

上一篇:JAVA: JDK动态代理


下一篇:jdk动态代理