浅析AOP实现原理(2)JDK动态代理

2017-10-14  本文已影响19人  挡不住的柳Willow

上一篇文章中我们聊了聊静态代理的实现,除了静态代理,AOP中主要用到的是动态代理即JDK动态代理和CGLIB动态代理

jdk动态代理

jdk动态代理是运行时JAVA反射机制生成相应对象的代理类而程序员手动编码生成,其中主要用到接口InvocationHandler和一个类Proxy

Proxy类

 public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
   .....
    }

Proxy类最重要的方法就是newProxyInstance,参数如下:
@loader 类加载器,用于生成代理类的实例
@interfaces 基础接口
@h 你所实现的InvocationHandler
在输入方法所需要的参数后,它会生成一个代理对象,并在调用者调用委托对象的方法时,invocationHandler的invoke方法会被触发(具体见下面)

InvocationHandler接口

public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

这个接口中只提供了一个invoke方法,方法参数如下:
@proxy 代理调用该方法的代理实例
@method 要调用的方法
@args 方法中的参数
invoke方法中,我们可以调用method的invoke(委托对象,方法参数)方法来间接调用委托对象中的方法,也能在该方法前后做一些额外的处理,该方法是AOP所实现的共同逻辑所在

实现过程

还是用上一篇文章的杀手例子

1、首先定义一个委托接口
public interface Killer {
    void kill();
}
2、生成委托类
public class KillerImpl implements Killer{
    @Override
    public void kill() {
        // TODO Auto-generated method stub
        System.out.println("正在杀人,请勿打扰");
    }
}
3、生成InvocationHandler实现类

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

public class ProxyClient implements InvocationHandler{
    private Object object;

    public ProxyClient(Object object) {
        this.object = object;
    }

    public static Object getProxy(Object object){
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),
                new ProxyClient(object));
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("我准备杀人啦");
        Object result = method.invoke(object, args);
        System.out.println("杀完啦");
        return result;
    }
}
4、测试
public class TestKiller {
    public static void main(String[] args) {
        Killer killer = (Killer) ProxyClient.getProxy(new KillerImpl());
        killer.kill();
    }
}
5、输出结果
image.png
上一篇下一篇

猜你喜欢

热点阅读