简单理解jdk的动态代理
1. 静态代理
静态代理其实就是我们的装饰者设计模式,首先定义一个接口类,然后定义这个接口类的实现类,对每一个实现类定义一个代理类,这里面代理类里面传入这个实现类的引用。
1.1 接口类
public interface PersonInterface { void say(); }
1.2 实现类
public class Students implements PersonInterface{ @Override public void say() { System.out.println("会说英语"); } }
1.3 代理类
public class StudentProxy implements PersonInterface{ private Students students = new Students(); @Override public void say() { System.out.println("111"); students.say(); System.out.println("222"); } }
1.4 测试类
public static void main(String[] args){ PersonInterface students = new StudentProxy(); students.say(); }
2. 动态代理
动态代理就是程序在运行期间,通过反射机制来实现对原始类的代理。首先定义一个接口类,在定义一个接口类的实现类,然后定义一个代理类。
2.1 接口类
public interface PersonInterface { void say(); }
2.2 实现类
public class Persons { public void say() { System.out.println("会说英语"); } }
2.3 代理类
public class Proxys implements InvocationHandler { private Object object; public Proxys(Object object){ this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("3333"); method.invoke(object,args); System.out.println("4444"); return null; } }
这个动态代理类主要是实现InvocationHandler接口,定义构造方法,里面用来传入代理类的对象,里面的invoke方法有三个参数,分别是proxy,method,args[] ,它们主要对应代理对象,真实对象的方法,真实对象方法的参数。
2.4 测试类
public static void main(String[] args){ Students students = new Students(); InvocationHandler proxys = new Proxys(students); PersonInterface p =(PersonInterface)Proxy.newProxyInstance(students.getClass().getClassLoader(),students.getClass().getInterfaces(),proxys); p.say(); }
3. 比较静态代理和动态代理和cglib代理
3.1 静态代理主要是一个实现类对应一个代理类,这样的话,如果实现类比较多的话,那么它将产生许多代理类,是面向接口编程,在编译已经产生与之对应的代理类。
3.2 动态代理使用接口编程,它的优点就是,很多个实现类可以用一个代理类,主要采用反射技术在运行期对实现类进行代理
3.3 cglib主要是因为jdk动态代理必须实现对应的接口,所以cglib就来解决没有接口时的代理,主要是通过字节码技术来实现代理,定义一个类,这个类就是父类被代理的类,然后cglib通过字节码技术生成一个子类,通过子类来完成对里面方法的增强,所以这就需要父类不能用final进行修饰。
3.4 什么时候用cglib代理?什么使用jdk动态代理?
如果是单例类的话,就使用cglib代理,不用产生很多的类,如果产生很多对象时,就是用jdk动态代理,cglib的性能比jdk代理的性能高