摘要:
Spring Framwork的兩大核心技術(shù)就是IOC和AOP,AOP在Spring的產(chǎn)品線中有著大量的應(yīng)用。如果說反射是你通向高級的基礎(chǔ),那么代理就是你站穩(wěn)高級的底氣。AOP的本質(zhì)也就是大家所熟悉的CGLIB動態(tài)代理技術(shù),在日常工作中想必或多或少都用過但是它背后的秘密值得我們?nèi)ド钏?。本文主要?code>Spring AOP運行過程上,結(jié)合一定的源碼整體上介紹Spring AOP的一個運行過程。知其然,知其所以然,才能更好的駕馭這門核心技術(shù)。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
//表明該類采用CGLIB代理還是使用JDK的動態(tài)代理
boolean proxyTargetClass() default false;
/**
* @since 4.3.1 代理的暴露方式:解決內(nèi)部調(diào)用不能使用代理的場景 默認為false表示不處理
* true:這個代理就可以通過AopContext.currentProxy()獲得這個代理對象的一個副本(ThreadLocal里面),從而我們可以很方便得在Spring框架上下文中拿到當(dāng)前代理對象(處理事務(wù)時很方便)
* 必須為true才能調(diào)用AopContext得方法,否則報錯:Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.
*/
boolean exposeProxy() default false;
}
所有的EnableXXX驅(qū)動技術(shù)都得看他的@Import,所以上面最重要的是這一句@Import(AspectJAutoProxyRegistrar.class),下面看看它
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AspectJAutoProxyRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注冊了一個基于注解的自動代理創(chuàng)建器 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
//表示強制指定了要使用CGLIB
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//強制暴露Bean的代理對象到AopContext
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
AspectJAutoProxyRegistrar是一個項容器注冊自動代理創(chuàng)建器
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
說明:spring容器的注解代理創(chuàng)建器就是AnnotationAwareAspectJAutoProxyCreator
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//這里如果我們自己定義了這樣一個自動代理創(chuàng)建器就是用我們自定義的
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
/**
*用戶注冊的創(chuàng)建器,必須是InfrastructureAdvisorAutoProxyCreator
*AspectJAwareAdvisorAutoProxyCreator,AnnotationAwareAspectJAutoProxyCreator之一
*/
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
//若用戶自己沒有定義,那就用默認的AnnotationAwareAspectJAutoProxyCreator
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
//此處注意,增加了一個屬性:最高優(yōu)先級執(zhí)行,后面會和@Async注解一起使用的時候起關(guān)鍵作用
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
我們就成功的注入了一個Bean:AnnotationAwareAspectJAutoProxyCreator 基于注解的自動代理創(chuàng)建器
Spring中自動創(chuàng)建代理器

由此可見,Spring使用BeanPostProcessor讓自動生成代理?;?code>BeanPostProcessor的自動代理創(chuàng)建器的實現(xiàn)類,將根據(jù)一些規(guī)則在容器實例化Bean時為匹配的Bean生成代理實例。
AbstractAutoProxyCreator是對自動代理創(chuàng)建器的一個抽象實現(xiàn)。最重要的是,它實現(xiàn)了SmartInstantiationAwareBeanPostProcessor接口,因此會介入到Spring IoC容器Bean實例化的過程。
SmartInstantiationAwareBeanPostProcessor繼承InstantiationAwareBeanPostProcessor所以它最主要的 職責(zé)是在bean的初始化前,先會執(zhí)行所有的InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation,誰第一個返回了不為null的Bean,后面就都不會執(zhí)行了 。然后會再執(zhí)行BeanPostProcessor#postProcessAfterInitialization
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
說明:這個方法是spring的三級緩存中的其中一環(huán),當(dāng)你調(diào)用Object earlySingletonReference = getSingleton(beanName, false);時候就會觸發(fā),其實還有一個地方exposedObject = initializeBean(beanName, exposedObject, mbd);也會觸發(fā)導(dǎo)致返回一個代理對象。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
強調(diào): 這2個地方雖然都有后置增強的作用,但是@Async所使用的AsyncAnnotationBeanPostProcessor不是SmartInstantiationAwareBeanPostProcessor的實現(xiàn)類,所以此處會導(dǎo)致@Transactional和@Async處理循環(huán)依賴時候的不一致性。對于循環(huán)依賴后續(xù)會有單獨章節(jié)進行分享。
AbstractAdvisorAutoProxyCreator
如何創(chuàng)建代理對象后續(xù)文章在進行分析。