1.动态代理 AOP底层实现:有接口自动应用的就是JDK动态代理
JDK代理是不需要依赖第三方的库,只要JDK环境就可以进行代理,它有几个要求
* 实现InvocationHandler
* 使用Proxy.newProxyInstance产生代理对象
* 被代理的对象必须要实现接口
使用JDK动态代理,目标类必须实现的某个接口,如果某个类没有实现接口则不能生成代理对象。
CGLib 必须依赖于CGLib的类库,Cglib原理是针对目标类生成一个子类,覆盖其中的所有方法,
所以目标类和方法不能声明为final类型。针对接口编程的环境下推荐使用JDK的代理。从执行效率上看,
Cglib动态代理效率较高。在Hibernate中的拦截器其实现考虑到不需要其他接口的条件Hibernate中的
相关代理采用的是CGLib来执行。
1)JDK 在运行时运行时注入
本质:在内存中构建出接口的实现类
特点:被代理对象,必须有接口
案例:
public interface ISomeService { public void doSome(); } ClassLoader(类加载器) loader, Class<?>[] interfaces, InvocationHandler h Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) InvocationHandler调度处理器 public interface InvocationHandler { } ------------------------Code-------------- final IUSerDao dao=new UserDaoImpl(); import java.lang.reflect.Proxy; InvocationHandler ih=new InvocationHandler(){ public Object invoke(Object proxy,Method method,Object[] args){ ==================前置=================== Object result=method.invoke(dao,args); ==================后置=================== return result; } }; IUSerDao proxy=(IUSerDao)Proxy.newProxyInstance(ClassLoader,Interfaces,InvocationHanlder){ }; proxy.add();
2)Cglib 底层,注入,编译期已经注入了
本质:在内存中生成被代理类(目标类)的【子类】
特点:可以在没有接口的情况下代理
对于不使用接口的业务类,无法使用JDK动态代理,cglib采用非常底层的字节码技术,
可以为一个类创建子类
案例:
public class SomeserviceImpl { public void doSome(){ System.out.println("===最后===="); } }
public class Test { /* * CGLIB动态代理 * */ public static void main(String[] args) { final SomeserviceImpl someservice=new SomeserviceImpl(); Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(someservice.getClass()); enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("===之前==="); methodProxy.invoke(someservice,objects); return null; } }); SomeserviceImpl service=( SomeserviceImpl)enhancer.create(); service.doSome(); } }
运行 结果: 将Test的输出语句结果在运行结果之前显示出来