Spring AOP简单分析

AOP解决的问题


1,代码重复
2,切面分离
(分离功能性需求与非功能请求)无侵入
非功能需求:权限控制,缓存控制,事务控制,性能监控,异常处理等

织入分为:
编译时期织入,加载时期织入,运行时期织入


Spring AOP属于运行时期织入

运行时织入实现:
静态代理和动态代理
代理又分为基于接口的代理实现和基于继承的代理实现

静态代理:客户端通过接口引用目标对象;目标对象和代理对象共同作为接口的实现类(因为目标对象中的方法代理对象中都要有);代理对象把真正的方法委托给目标对象来执行,代理对象自己则执行需要织入的一些逻辑以及捕获并抛出异常.

具体实现:

静态代理的缺点:
如果代理的方法越多,重复的逻辑就越多,比如一百个方法,代理类就需要委托一百个给目标类,则可能出现大量逻辑重复

动态代理:
分为基于接口的代理和基于继承的代理

代表分别为JDK代理和Cglib代理
JDK代理实现要点 :
1,通过类java.lang.reflect.Proxy来动态生成代理类
2,代理类实现InvocationHandler接口
3,只能基于接口进行动态代理

通过基于方法的反射生成对象:
在Proxy类中实现InvocationHandler接口:
Object object = method.invoke(实现类对象,参数);
JDK代理在客户端实现:

JDK代理源码解析:

Proxy.newProxyInstance是通过getProxyClass()方法生成字节码(getProxyClass()调用了ProxyClassFactory(),接着ProxyClassFactory()调用ProxyGenerator()),然后通过java反射newInstance将字节码生成实例.
原理就是我们实现类有几种方法那么生成的字节码就有几种方法,并通过invoke生成实例方法

Cglib代理实现要点:
1,通过继承的方法实现代理类
2,通过callbake(回调函数)方式来织入我们需要的代码

JDK与Cglib代理对比:
1,JDK只能针对有接口的类的接口方法进行动态代理
2,Cglib基于继承来实现代理,无法对static,finnal类进行代理;也无法对private,static方法进行代理


Spring是怎么选择的呢?

1,如果目标对象实现了接口,则默认使用JDK动态代理
2,如果目标对象没有实现接口,则采用Cglib进行动态代理
3,如果目标对象实现了接口,且强制使用cglib代理,则使用cglib代理

多个AOP作用于同一个实例对象是如何叠加的?
答案是使用了责任链模式


 

猜你喜欢

转载自blog.csdn.net/ailaojie/article/details/89196485