核心概念
advice:通知,就是你想要實(shí)現(xiàn)的功能,比如日志、事務(wù)
JoinPoint:切點(diǎn),理解為需要切入的方法
Pointcut:切入點(diǎn),理解為需要切入的方法的位置
Aspect(Advisor): Aspect=advice+Pointcut,切面=干什么+在哪干
AOP源碼解析
AOP切面方法調(diào)用流程分析
1、解析注解獲取所有的通知advisor列表
2、根據(jù)通知列表構(gòu)造增強(qiáng)鏈chain,對原始方法進(jìn)行增強(qiáng)。這一過程通過調(diào)用時(shí)執(zhí)行ReflectiveMethodInvocation.proceed方法實(shí)現(xiàn)。
3、DynamicAdvisedInterceptor是enhance的interceptor。負(fù)責(zé)構(gòu)造MethodInvocation并調(diào)用proceed方法。把對原始方法的調(diào)用委托給methodInvocation。
4、MethodInvocation里面是aop的interceptor。aop的interceptor接口如下
public interface MethodInterceptor extends Interceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}
常見的aop的Interceptor有:MethodBeforeAdviceInterceptor,AfterAdviceInterceptor,AspectJAroundAdvice,AspectJAfterReturningAdvice,AspectJAfterThrowingAdvice
5、通過method.invoke實(shí)現(xiàn)切面方法的調(diào)用
判斷一個(gè)類是否需要增強(qiáng)以及增強(qiáng)哪些切面
AbstractAutoProxyCreator有如下重要屬性:
advisedBeans:保存哪些bean需要增強(qiáng)。對應(yīng)的bean的方法中滿足advises增強(qiáng)太條件的那些bean
advisorsCache:通知緩存,key為通知名(logAspecct),value為該通知對應(yīng)的Advisor列表
1、AbstractAutoProxyCreator.postProcessAfterInitialization會檢查每個(gè)bean通過wrapIfNecessary判斷是否需要生成代理類;
2、findCandidateAdvisors找出所有的advised:找出所有含有@Aspect注解的bean;過濾出該類中非@Pointcut注解的方法,每個(gè)方法都封裝成一個(gè)Advisor,并放入advisorsCache;
3、過濾出可匹配當(dāng)前bean的advsior,調(diào)用AopUtils.findAdvisorsThatCanApply.
類增強(qiáng)的代碼實(shí)現(xiàn)
參考CglibAopPoxy.getProxy方法
ProxyFactory構(gòu)造時(shí)候傳入TargetSource
1、從TargetSource獲取待增強(qiáng)的目標(biāo)類
2、檢查類增強(qiáng)限制:非final類,非final方法
3、Enhancer的Interceptor:SpringProxy(標(biāo)識是否是spring aop產(chǎn)生的代理類)和Advised。
4、Enhancer的Callbacks設(shè)置,該數(shù)組共有7個(gè)元素:StaticUnadvisedInterceptor。
5、設(shè)置Enhancer的ProxyCallbackFilter。
DynamicAdvisedInterceptor
StaticunadvisedInterceptor
SerializableNoOp:對應(yīng)final,不做增強(qiáng)
EqualsInterceptor
DynamicAdvisedInterceptor方法
每個(gè)待增強(qiáng)的方法都會操作一遍
1、調(diào)用getInterceptorsAndDynamicInterceptionAdvice,構(gòu)造攔截的chain。
2、aop各個(gè)advise的調(diào)用在ReflectiveMethodInvocation.proceed
3、ReflectiveMethodInvocation封裝了chain列表,和index指示器,會遞歸調(diào)用全部的interceptors。
4、調(diào)用的第一個(gè)aopinterceptor是ExposeInvocationInterceptor,用于保存MethodInvocation上下文,該interceptor優(yōu)先級最高,值最小,最先執(zhí)行
Objenesis Vs class.newInstance
從以上代碼可以發(fā)現(xiàn)class構(gòu)造器需要參數(shù),而Objenesis可以繞過去, Objenesis主要應(yīng)用場景:
- 序列化,遠(yuǎn)程調(diào)用和持久化 -對象需要實(shí)例化并存儲為到一個(gè)特殊的狀態(tài),而沒有調(diào)用代碼。
- 代理,AOP庫和Mock對象 -類可以被子類繼承而子類不用擔(dān)心父類的構(gòu)造器。
- 容器框架 -對象可以以非標(biāo)準(zhǔn)的方式被動態(tài)實(shí)例化。
詳細(xì)參考:https://blog.csdn.net/codershamo/article/details/52015206
生成代理對象AopProxy
有兩種方式CglibAopProxy和JdkDynamicAopProxy
ApplicationContext.refresh->registerBeanPostProcessors
aop源碼分析:https://zhuanlan.zhihu.com/p/35135042
jdk動態(tài)代理
InvocationHandler = {}
People proxy = (People)Proxy.newProxyInstance(handler.getClass().getClassLoader(), people.getClass().getInterfaces(), handler);
cglib增強(qiáng)原理
cglib詳解:https://blog.csdn.net/zghwaicsdn/article/details/50957474
cglib用法樣例
public class ServiceCgInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before");
Object ret = methodProxy.invokeSuper(o, objects);//調(diào)用原始
System.out.println("after");
return ret;
}
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(ServiceCg.class);
enhancer.setCallback(new ServiceCgInterceptor());
ServiceCg proxy = (ServiceCg) enhancer.create();
proxy.say1();
}
}
如果增強(qiáng)一個(gè)類需要用到多個(gè)Interceptor,實(shí)現(xiàn)如下:
enhancer.setCallbacks(cbarray);
enhancer.setCallbackFilter(callbackFilter); //CallbackFilter返回對應(yīng)callback的index