本文主要是介绍AOP动态代理织入,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在之前一篇中,我们介绍了什么是AOP面向切面编程。下面以Spring AOP 为例来详细讲解。
Spring AOP 采用的是动态代理织入
代理是实现AOP的底层技术。
下面介绍两种代理技术:
1. JDK代理技术
2. CGlib代理技术
JDK代理:
InvocationHandler 是一个接口,增强逻辑代码就是放在这个接口的实现类中。
代理类= 目标类 + 增强逻辑。相当于一个新类。
package com.smart.proxy;import java.lang.reflect.InvocationHandler; //相当于一个编织器,将切面织入目标类
import java.lang.reflect.Method;public class PerformaceHandler implements InvocationHandler {private Object target; //目标类public PerformaceHandler(Object target){this.target = target;}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {PerformanceMonitor.begin(target.getClass().getName()+"."+ method.getName());//逻辑代码Object obj = method.invoke(target, args);//反射调用目标对象的方法PerformanceMonitor.end();//横切逻辑代码return obj;}
}
PerformaceHander 为一个编织器对象
@Testpublic void proxy() {// 业务类正常编码的测试// ForumService forumService = new ForumServiceImpl();// forumService.removeForum(10);// forumService.removeTopic(1012);// 使用JDK动态代理ForumService target = new ForumServiceImpl();//目标类PerformaceHandler handler = new PerformaceHandler(target);//编织器类,在目标类中织入相应的代码逻辑ForumService proxy = (ForumService) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), handler);//生成代理proxy.removeForum(10); // 按照目标类所显现接口来调用方法。(可以理解为接口的代理)proxy.removeTopic(1012);
proxy 通过静态方法,par1 为目标类的类加载器,par2为目标类的借口,par3位编织器对象。这样就生成了一个目标类增强后的代理类。proxy.调用代理对象的方法时,就会去执行invoke函数。从而实现代码注入
对于没有通过借口定义业务方法的类,我们就必须使用CGlib来操作。CGlib 采用底层的字节码技术,可以为一个类创建子类,在子类中采用方法拦截的技术拦截所有的父类方法,并顺势织入横切逻辑。
package com.smart.proxy;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;public class CglibProxy implements MethodInterceptor {//相当于一个代理创建器支持所有类private Enhancer enhancer = new Enhancer();public Object getProxy(Class clazz) { //获得代理类enhancer.setSuperclass(clazz); //设置目标类enhancer.setCallback(this);return enhancer.create();//创建代理类}public Object intercept(Object obj, Method method, Object[] args,//拦截父类所有方法的调用MethodProxy proxy) throws Throwable {PerformanceMonitor.begin(obj.getClass().getName()+"."+method.getName());//织入Object result=proxy.invokeSuper(obj, args);PerformanceMonitor.end();return result;}
}
下面看测试:
@Testpublic void proxy() {//使用CGLib动态代理CglibProxy cglibProxy = new CglibProxy(); //获取代理创建器ForumService forumService = (ForumService)cglibProxy.getProxy(ForumServiceImpl.class);//获取代理向上转型forumService.removeForum(10);//父类方法调用,会被intercept拦截,织入增加。forumService.removeTopic(1023);}
这篇关于AOP动态代理织入的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!