核心概念
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,對(duì)原始方法進(jìn)行增強(qiáng)服傍。這一過(guò)程通過(guò)調(diào)用時(shí)執(zhí)行ReflectiveMethodInvocation.proceed方法實(shí)現(xiàn)钱雷。
3、DynamicAdvisedInterceptor是enhance的interceptor吹零。負(fù)責(zé)構(gòu)造MethodInvocation并調(diào)用proceed方法罩抗。把對(duì)原始方法的調(diào)用委托給methodInvocation。
4灿椅、MethodInvocation里面是aop的interceptor套蒂。aop的interceptor接口如下
public interface MethodInterceptor extends Interceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}
常見(jiàn)的aop的Interceptor有:MethodBeforeAdviceInterceptor,AfterAdviceInterceptor,AspectJAroundAdvice,AspectJAfterReturningAdvice茫蛹,AspectJAfterThrowingAdvice
5操刀、通過(guò)method.invoke實(shí)現(xiàn)切面方法的調(diào)用
判斷一個(gè)類(lèi)是否需要增強(qiáng)以及增強(qiáng)哪些切面
AbstractAutoProxyCreator有如下重要屬性:
advisedBeans:保存哪些bean需要增強(qiáng)。對(duì)應(yīng)的bean的方法中滿(mǎn)足advises增強(qiáng)太條件的那些bean
advisorsCache:通知緩存婴洼,key為通知名(logAspecct)骨坑,value為該通知對(duì)應(yīng)的Advisor列表
1、AbstractAutoProxyCreator.postProcessAfterInitialization會(huì)檢查每個(gè)bean通過(guò)wrapIfNecessary判斷是否需要生成代理類(lèi);
2欢唾、findCandidateAdvisors找出所有的advised:找出所有含有@Aspect注解的bean且警;過(guò)濾出該類(lèi)中非@Pointcut注解的方法,每個(gè)方法都封裝成一個(gè)Advisor礁遣,并放入advisorsCache斑芜;
3、過(guò)濾出可匹配當(dāng)前bean的advsior祟霍,調(diào)用AopUtils.findAdvisorsThatCanApply.
類(lèi)增強(qiáng)的代碼實(shí)現(xiàn)
參考CglibAopPoxy.getProxy方法
ProxyFactory構(gòu)造時(shí)候傳入TargetSource
1杏头、從TargetSource獲取待增強(qiáng)的目標(biāo)類(lèi)
2、檢查類(lèi)增強(qiáng)限制:非final類(lèi)浅碾,非final方法
3大州、Enhancer的Interceptor:SpringProxy(標(biāo)識(shí)是否是spring aop產(chǎn)生的代理類(lèi))和Advised续语。
4垂谢、Enhancer的Callbacks設(shè)置,該數(shù)組共有7個(gè)元素:StaticUnadvisedInterceptor。
5疮茄、設(shè)置Enhancer的ProxyCallbackFilter滥朱。
DynamicAdvisedInterceptor
StaticunadvisedInterceptor
SerializableNoOp:對(duì)應(yīng)final,不做增強(qiáng)
EqualsInterceptor
DynamicAdvisedInterceptor方法
每個(gè)待增強(qiáng)的方法都會(huì)操作一遍
1力试、調(diào)用getInterceptorsAndDynamicInterceptionAdvice徙邻,構(gòu)造攔截的chain。
2畸裳、aop各個(gè)advise的調(diào)用在ReflectiveMethodInvocation.proceed
3缰犁、ReflectiveMethodInvocation封裝了chain列表,和index指示器怖糊,會(huì)遞歸調(diào)用全部的interceptors帅容。
4、調(diào)用的第一個(gè)aopinterceptor是ExposeInvocationInterceptor,用于保存MethodInvocation上下文伍伤,該interceptor優(yōu)先級(jí)最高并徘,值最小,最先執(zhí)行
Objenesis Vs class.newInstance
從以上代碼可以發(fā)現(xiàn)class構(gòu)造器需要參數(shù)扰魂,而Objenesis可以繞過(guò)去麦乞, Objenesis主要應(yīng)用場(chǎng)景:
- 序列化装诡,遠(yuǎn)程調(diào)用和持久化 -對(duì)象需要實(shí)例化并存儲(chǔ)為到一個(gè)特殊的狀態(tài)倔幼,而沒(méi)有調(diào)用代碼绽族。
- 代理擂送,AOP庫(kù)和Mock對(duì)象 -類(lèi)可以被子類(lèi)繼承而子類(lèi)不用擔(dān)心父類(lèi)的構(gòu)造器选浑。
- 容器框架 -對(duì)象可以以非標(biāo)準(zhǔn)的方式被動(dòng)態(tài)實(shí)例化惩歉。
詳細(xì)參考:https://blog.csdn.net/codershamo/article/details/52015206
生成代理對(duì)象AopProxy
有兩種方式CglibAopProxy和JdkDynamicAopProxy
ApplicationContext.refresh->registerBeanPostProcessors
aop源碼分析:https://zhuanlan.zhihu.com/p/35135042
jdk動(dòng)態(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è)類(lèi)需要用到多個(gè)Interceptor浸锨,實(shí)現(xiàn)如下:
enhancer.setCallbacks(cbarray);
enhancer.setCallbackFilter(callbackFilter); //CallbackFilter返回對(duì)應(yīng)callback的index