AOP

核心概念

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)用場景:

  1. 序列化,遠(yuǎn)程調(diào)用和持久化 -對象需要實(shí)例化并存儲為到一個(gè)特殊的狀態(tài),而沒有調(diào)用代碼。
  2. 代理,AOP庫和Mock對象 -類可以被子類繼承而子類不用擔(dān)心父類的構(gòu)造器。
  3. 容器框架 -對象可以以非標(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

原理詳解

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容