原理区别:
java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
JDK动态代理和CGLIB字节码生成的区别?
(1)JDK动态代理只能对实现了接口的类生成代理,而不能针对类
(2)CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
因为是继承,所以该类或方法最好不要声明成final
实现方式区别:
1.JDK动态代理是实现了被代理对象的接口,Cglib是继承了被代理对象。
2.JDK和Cglib都是在运行期生成字节码,JDK是直接写Class字节码,Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低。
3.JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法,Cglib执行效率更高。
jdk动态代理
执行流程:
1、为接口创建代理类的字节码文件
2、使用ClassLoader将字节码文件加载到JVM
3、创建代理类实例对象,执行对象的目标方法
package com.springboottest.helloword.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @author zx * @Title: TestActionProxy * @ProjectName helloword * @Description: TODO * @date 2019/10/26 22:37 */ interface adidasFactory{ void action(); } class Adidas implements adidasFactory{ @Override public void action() { System.out.println("Adidas生产了衣服"); } } class MyInvokeProxyHandler implements InvocationHandler { Object obj; public Object build(Object obj){ this.obj=obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("invoke被调用了前"); Object returnVal = method.invoke(obj,args); System.out.println("invoke被调用了后"); return returnVal; } } public class TestActionProxy { public static void main(String[] args) { Adidas cloth1 = new Adidas(); Object object = new MyInvokeProxyHandler().build(cloth1); adidasFactory factory =(adidasFactory)object; factory.action(); } }
cglib动态代理
package com.springboottest.helloword.proxy; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * @author zhao xin * @Title: TestCglibProxy * @ProjectName helloword * @Description: TODO * @date 2019/10/27 20:43 */ class BookFacadeImpl1{ public void addBook() { System.out.println("增加图书的普通方法..."); } } class BookFacadeCglib implements MethodInterceptor { private Object target; /** * 创建代理对象 * * @param target * @return */ public Object getInstance(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return enhancer.create(); } @Override // 回调方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("事物开始"); proxy.invokeSuper(obj, args); System.out.println("事物结束"); return null; } } public class TestCglibProxy { public static void main(String[] args) { BookFacadeImpl1 bf = new BookFacadeImpl1(); Object cglibObject = new BookFacadeCglib().getInstance(bf); BookFacadeImpl1 obj = (BookFacadeImpl1) cglibObject; obj.addBook(); } }