所有文章
https://www.cnblogs.com/lay2017/p/11478237.html
正文
spring的兩大核心就是ioc和aop。在關於ioc依賴注入的文章中,我們了解了如何根據BeanDefinition創建Bean,然后在BeanPostProcessor中處理@Autowired和@Resource兩個注解,自動注入Bean。
本文將講解另外一塊核心內容,aop切面。
AOP自動配置
首先,aop切面基於springboot的自動配置。如果不了解自動配置,請參考自動配置機制的文章。
為此,我們先找到aop自動配置的類AopAutoConfiguration
@Configuration @ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class }) @ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true) public class AopAutoConfiguration { @Configuration @EnableAspectJAutoProxy(proxyTargetClass = false) @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false) public static class JdkDynamicAutoProxyConfiguration { } @Configuration @EnableAspectJAutoProxy(proxyTargetClass = true) @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true) public static class CglibAutoProxyConfiguration { } }
我們將以Cglib為主要的了解對象,可以看到CglibAutoProxyConfiguration上注解了一個@EnableAspectJAutoProxy,它意味着開啟切面代理,我們打開該注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { // }
我們看到,@Import注解導入了AspectJAutoProxyRegistrar。在自動配置的文章中,我們了解到ConfigurationClassParser將會處理@Import注解。這里我們不再關注如何處理@Import注解,直接打開AspectJAutoProxyRegistrar類看看
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 注冊自動切面代理的創建器 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); // 省略 } }
跟進registerAspectJAnnotationAutoProxyCreatorIfNecessary
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null); }
繼續跟進registerAspectJAnnotationAutoProxyCreatorIfNecessary
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
我們看到,調用registerOrEscalateApcAsRequired方法指定了一個類AnnotationAwareAspectJAutoProxyCreator,這個類將作為創建代理的類
跟進registerOrEscalateApcAsRequired方法
private static BeanDefinition registerOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { // // 構建BeanDefinition RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); // 注冊到Bean容器 registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
可以看到,最終是注冊到了Bean容器中,作為BeanDefinition存在。我們可以認為aop的自動配置過程就是為了創建AnnotationAwareAspectJAutoProxyCreator這個類的BeanDefinition。
注冊AnnotationAwareAspectJAutoProxyCreator
首先,我們先看看AnnotationAwareAspectJAutoProxyCreator的繼承結構
可以看到,AnnotationAwareAspectJAutoProxyCreator最終是實現了BeanPostProcessor,那BeanPostProcessor是什么時候被創建為Bean的呢?
這里,我們得回到refresh容器過程的refresh方法中,跟進AbstractApplicationContext的refresh方法
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // try { // // 注冊BeanDefinition到容器 invokeBeanFactoryPostProcessors(beanFactory); // 注冊后置處理器到容器 registerBeanPostProcessors(beanFactory); // } // } }
在注冊BeanDefinition之后,就會把BeanPostProcessor的BeanDefinition轉化為了Bean注冊到容器中。registerBeanPostProcessors結束以后,AnnotationAwareAspectJAutoProxyCreator就以Bean的形式存在於BeanFactory中了。
觸發AnnotationAwareAspectJAutoProxyCreator
接着,我們再看AnnotationAwareAspectJAutoProxyCreator被注冊為Bean以后,是在什么位置被觸發的。前面,ioc依賴注入的文章中我們提到過createBean方法,將會根據BeanDefinition創建Bean。
跟進AbstractAutowireCapableBeanFactory的createBean方法
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // try { // BeanPostProcessors 調用 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } // try { // 創建實例對象 Object beanInstance = doCreateBean(beanName, mbdToUse, args); // return beanInstance; } // }
我們看到,在doCreateBean之前,先觸發resolveBeforInstantiation方法,調用了AnnotationAwareAspectJAutoProxyCreator。
切面解析
跟進resolveBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { // if (targetType != null) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); // } } // } return bean; }
繼續跟進applyBeanPostProcessorBeforeInstantiation方法
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 觸發postProcesBeforeInstantiation Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
繼續跟進AbstractAutoProxyCreator的postProcessBeforeInstantiation方法
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { // if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } // return null; }
isInfrastructureCLass將返回false,跟進AspectJAwareAdvisorAutoProxyCreator的shouldSkip
protected boolean shouldSkip(Class<?> beanClass, String beanName) { // 返回所有的通知,如@Before @After @AfterThrowing @Round List<Advisor> candidateAdvisors = findCandidateAdvisors(); for (Advisor advisor : candidateAdvisors) { if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } return super.shouldSkip(beanClass, beanName); }
這里的findCandidateAdvisors方法,將會從beanFactory中獲得注解了@Aspect的類元數據,然后獲取其中定義的Advisor。
到這一步,我們就已經獲得了完成了切面部分的解析工作。
代理增強
回到AbstractAutowireCapableBeanFactory的createBean方法
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // try { // BeanPostProcessors 調用 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } // try { // 創建實例對象 Object beanInstance = doCreateBean(beanName, mbdToUse, args); // return beanInstance; } // }
獲取了Advisor,那么再看看Advisor被增強到Bean上的過程,跟進doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // if (instanceWrapper == null) { // 創建實例對象 instanceWrapper = createBeanInstance(beanName, mbd, args); } // Object exposedObject = bean; try { // 自動注入 populateBean(beanName, mbd, instanceWrapper); // 初始化Bean,創建代理的入口 exposedObject = initializeBean(beanName, exposedObject, mbd); } // return exposedObject; }
我們找到initializeBean,這個初始化Bean的入口,將從這里開始關注代理增強部分,跟進initializeBean方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { // if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
繼續跟進applyBeanPostProcessorsAfterInitialization方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
這里將會調用AbstractAutoProxyCreator的postProcessAfterInitialization方法,跟進方法
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
繼續跟進wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { // // 獲取適用於當前Bean的Advisors Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 創建代理 Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
getAdvicesAndAdvisorsForBean方法將會獲取到可以增強到該Bean的Advisor,然后createProxy將會創建代理類,並一路返回,如果是單例,則注冊到緩存中
跟進createProxy看看創建代理
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { // // 獲取可用的advisor Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); // // 創建並返回代理對象 return proxyFactory.getProxy(getProxyClassLoader()); }
跟進getProxy
public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); }
createAopProxy將會根據條件返回Cglib實現或者jdk動態代理的實現,然后調用它們的getProxy方法去獲取代理對象
總結
本文省略了不少細節內容,大體邏輯是從:aop自動配置 -> 解析@Aspect切面對象 -> 代理增強,這么一個邏輯行文的。
自動配置的核心就是為了導入一個AnnotationAwareAspectJAutoProxyCreator,該類實現了BeanPostProcessor。所以在創建Bean實例對象之前會觸發解析@Aspect切面對象,獲取Advisor。在生成Bean實例對象之后,會再觸發該類對Bean實例對象做代理增強,增強的Advisor來自之前的解析結果。代理增強的實現有cglib和jdk動態代理兩種。
最后,增強過的代理Bean如果是單例,將跟以前一樣添加到緩存對象中。