对JDK动态代理的理解和实现(个人理解)

如果我们想在原先已经写好的方法前后加一些东西,如生成日志文件等等,要怎么办呢?

考虑到代码的开闭性原则,我们最好不要在源代码中进行修改,这样会导致两点不便:①可能导致之前代码不可用 ②如果每个方法都要加生成日志的代码,会导致代码冗余和可维护性差。

这个时候我们就会用到动态代理,动态代理分为两种。JDK动态代理和Cgilb动态代理。

两种用法分情况使用,如果方法类实现了接口,可以使用JDK动态代理或者强制使用cglib动态代理

                                    如果方法类没有实现接口,只能使用cglib动态代理。

一、个人理解JDK动态代理

 动态代理比较原生,底层用到的是反射机制。原理步骤为:

1.首先有一个目标对象(就是最原本的对象),实现一个接口

2.有一个增强对象(里面为最终要实现的方法的对象,包括前缀后缀和目标对象的原方法),该方法要实现invocationhandler接口,并重写invoke方法

3.将目标对象和增强对象结合起来生成一个代理对象

4.调用代理对象的方法

代码体现:

目标对象

public class Mi implements Imi{
    public void Note() {
        System.out.println("生产Note");
    }
    public void Note2() {
        System.out.println("生产Note2");
    }
}

 

目标对象实现的接口

public interface Imi {
    void Note();
    void Note2();
}

 

增强对象

public class ProxyMi implements InvocationHandler{

    //获取到当前要代理的对象
    private Object target;
    public ProxyMi(Object target) {
        // TODO Auto-generated constructor stub
        this.target=target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        method.invoke(target, args);
        System.out.println("销售");
        return null;
    }
    

测试文件

public class MyTest {
    public static void main(String[] args) {

        //声明目标对象(相当于代理对象的父亲)
        Mi mi=new Mi();

        //将目标对象和增强对象结合(增强对象相当于代理对象的母亲,这一步相当于父母结合)
        ProxyMi proxyMi = new ProxyMi(mi);
        Class[] classes= {Imi.class};

        //通过接口类、增强对象创建代理对象(相当于生了个孩子有父母两个人的特性)
        Object newProxyInstance = Proxy.newProxyInstance(Mi.class.getClassLoader(), classes,proxyMi);
        Imi mi2=(Imi)newProxyInstance;

       //最后调用代理对象的方法
        mi2.Note2();
    }
}
}

二、个人理解cglib动态代理

不同于JDK动态代理,他不是对应相应的接口生成一个新的类,而是针对之前的方法类生成一个他的子类。

 

输出结果

完成

你可能感兴趣的:(对JDK动态代理的理解和实现(个人理解))