作為 Spring 體系里的大塊頭校摩,AOP用起來是很爽,但是問你它是怎么實(shí)現(xiàn)的阶淘,你就懵逼衙吩。嘿嘿嘿 ~
還是從 SpringBoot 的啟動(dòng)流程來講起,看看定義切面后的啟動(dòng)流程溪窒。
先看我們的測試?yán)樱?/p>
TestController.java :
LogAspect.java :
接下來坤塞,從啟動(dòng)流程看冯勉,TestController 和 LogAspect是怎么創(chuàng)建的。
我們找到 AbstractAutowireCapableBeanFactory#initializeBean() 方法尺锚,如圖:
別問我怎么找到這個(gè)方法的珠闰,我不會(huì)告訴你是打了九九八十一個(gè)斷點(diǎn)調(diào)出來的 =。=
進(jìn)入 applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName) 方法瘫辩,看下參數(shù):
遍歷到 AnnotationAwareAspectJAutoProxyCreator 這個(gè)processor的時(shí)候伏嗜,debug進(jìn)去,可以看到:
這個(gè) wrapIfNecessary()方法就很關(guān)鍵了伐厌,再點(diǎn)進(jìn)去:
可以看到這一步里承绸,先是找到所有的通知器(攔截器或者增強(qiáng)器),然后接下來創(chuàng)建proxy:
點(diǎn)擊createProxy()挣轨,進(jìn)入军熏,看核心代碼代碼:
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
……
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
……
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
return proxyFactory.getProxy(classLoader);
}
可以看到,這里都是對(duì) proxyFactory 進(jìn)行設(shè)置的卷扮。點(diǎn)擊 proxyFactory.getProxy(classLoader) 荡澎,一直追到
DefaultAopProxyFactory # createAopProxy( ),這里就是創(chuàng)建代理的核心了:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 如果開啟了優(yōu)化晤锹,或者 ProxyTargetClass設(shè)置為true摩幔,或者沒有代理類要實(shí)現(xiàn)的接口
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 如果targetClass(這里是指我們調(diào)試的 TestController.class) 是接口或者代理類,則創(chuàng)建jdk動(dòng)態(tài)代理鞭铆,否則返回 cglib 代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
createAopProxy() 之后是 getProxy()或衡,以 CglibAopProxy#getProxy() 為例:
public Object getProxy(@Nullable ClassLoader classLoader) {
try {
……
// 配置 CGLIB 增強(qiáng)器
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
enhancer.setSuperclass(proxySuperClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
// 獲取代理的回調(diào)方法
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// 生成代理類和實(shí)例
return createProxyClassAndInstance(enhancer, callbacks);
}
}
大概流程就是這樣了〕邓欤總結(jié)一下封断,就是根據(jù)我們的目標(biāo)類,生成jdk動(dòng)態(tài)代理或者cglib代理舶担,后面執(zhí)行到這個(gè)目標(biāo)類(例子中是TestController) 的時(shí)候坡疼,就用生成的代理類去執(zhí)行,而代理類里面有增強(qiáng)器衣陶,也就是我們的橫切面回梧。
下一節(jié)講講cglib 和 jdk 動(dòng)態(tài)代理工作的過程。