引入AOP--代理的比较

xiaoxiao2021-02-28  153

AOP(面向切面编程):

    切面:从业务逻辑分离出去的横切逻辑。典型:性能监控,日志管理,权限控制,可以从核心的业务逻辑中分离出去。

    通过AOP可以解决代码耦合问题,使职责更加单一。

对于需要增强的代码,我们通常有三种解决方案:

(1)静态代理

(2)JDK动态代理

(3)CGLib动态代理

静态代理:

   由程序员创建生成源代码,再对其进行编译,再程序运行时,class文件就已经存在了。(创建代理类去进行代理,但每有一个需要代理的类,都要创建相应的代理类。随着后期的发展,这种代理类会越来越多。这种方式过于繁琐,需要优化的是只生成一个代理类,让需要被代理的类都依赖这个代理类,这就需要动态代理)。

JDK动态代理:

在程序运行时,通过反射机制动态生成代理。避免编写各个繁琐的静态代理类,

动态代理三个步骤:

(1)编写自定义的InvocationHandler来实现InvocationHandler接口

(2)创建动态代理对象。

(3)代理对象调用

public class MyinvocationHandler implements InvocationHandler { private Object target; public MyinvocationHandler(Object target) { this.target = target; } /** *获取代理对象 */ public Object getProxy(){ return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); Object rs = method.invoke(target,args); after(); return rs; } public void before(){ System.out.println("开始前"); } public void after(){ System.out.println("开始后"); } }JDK动态代理只能代理具有接口的类,不能代理没有接口的类,开源的CGLIb类库具有代理没有接口的类的能力,弥补了JDK的不足。

CGLIB动态代理:采用了底层的字节码技术,通过字节码技术为一个类创建子类,并在子类中对所有方法进行拦截来实现对父类方法的拦截,从而织入横切逻辑,是实现AOP的基础。

public class cglibProxy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz){ //传入父类字节码 enhancer.setSuperclass(clazz); enhancer.setCallback(this); //字节码技术创建子类 return enhancer.create(); } //intercept用于拦截方法的调用(这里可以进行增强的处理) public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("增强前"); //调用父类的目标方法 Object result = methodProxy.invokeSuper(obj,objects); System.out.println("增强后"); return result; } } getProxy()方法通过传入父类的字节码,创建其子类,intercept()通过对子类方法的拦截来拦截对父类目标方法的调用,顺势织入横切逻辑,达到增强的效果。 对于JDK,CGLib两种动态代理:  JDK动态代理CGLIB动态代理接口必须不需要性能比cglib低 比JDK高耗时耗时相对短耗时长对于单例的对象,因为无需频繁创建对象,用CGLib合适,CGLIB对于final修饰的类无法进行代理。

转载请注明原文地址: https://www.6miu.com/read-17426.html

最新回复(0)