http://www.javashuo.com/article/p-uvudtich-bm.htmlhtml
spring的兩大核心就是ioc和aop。在關於ioc依賴注入的文章中,咱們瞭解瞭如何根據BeanDefinition建立Bean,而後在BeanPostProcessor中處理@Autowired和@Resource兩個註解,自動注入Bean。spring
本文將講解另一塊核心內容,aop切面。緩存
首先,aop切面基於springboot的自動配置。若是不瞭解自動配置,請參考自動配置機制的文章。springboot
爲此,咱們先找到aop自動配置的類AopAutoConfigurationapp
@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,它意味着開啓切面代理,咱們打開該註解ide
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { // }
咱們看到,@Import註解導入了AspectJAutoProxyRegistrar。在自動配置的文章中,咱們瞭解到ConfigurationClassParser將會處理@Import註解。這裏咱們再也不關注如何處理@Import註解,直接打開AspectJAutoProxyRegistrar類看看post
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 註冊自動切面代理的建立器 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); // 省略 } }
跟進registerAspectJAnnotationAutoProxyCreatorIfNecessaryui
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null); }
繼續跟進registerAspectJAnnotationAutoProxyCreatorIfNecessarythis
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
咱們看到,調用registerOrEscalateApcAsRequired方法指定了一個類AnnotationAwareAspectJAutoProxyCreator,這個類將做爲建立代理的類spa
跟進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最終是實現了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被註冊爲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若是是單例,將跟之前同樣添加到緩存對象中。