//EnableAspectJAutoProxy.java @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { /** * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed * to standard Java interface-based proxies. The default is {@code false}. */ boolean proxyTargetClass() default false; /** * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal} * for retrieval via the {@link org.springframework.aop.framework.AopContext} class. * Off by default, i.e. no guarantees that {@code AopContext} access will work. * @since 4.3.1 */ boolean exposeProxy() default false; }
上述代碼是springAop源碼的最主要的註解;下邊咱們來分析下AspectJAutoProxyRegistrar.javajava
//AspectJAutoProxyRegistrar.java class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { /** * Register, escalate, and configure the AspectJ auto proxy creator based on the value * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing * {@code @Configuration} class. */ @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //若是須要註冊AspectJ代理自動建立器 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } }
由上述代碼可知,AspectJAutoProxyRegistrar.java即AspectJ自動代理註冊組件,實現了ImportBeanDefinitionRegistrar接口,也就是自定義導入組件。git
咱們在AspectJAutoProxyRegistrar.java的45行打個斷點,進行調試github
2處加入了AnnotationAwareAspectJAutoProxyCreator.java 即AspectJ註解自動代理建立器,稍後咱們在分析spring
接下來咱們看registerOrEscalateApcAsRequired()方法:緩存
//AspectJAutoProxyRegistrar.java private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); //<1>判斷容器中有沒有org.springframework.aop.config.internalAutoProxyCreator if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } //<2>若是沒有在bean註冊org.springframework.aop.config.internalAutoProxyCreator RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
<1>由AUTO_PROXY_CREATOR_BEAN_NAME 可知確定是判斷是否容器中有internalAutoProxyCreator的beanapp
<2>沒有就建立一個ide
由類圖繼承關係可知AnnotationAwareAspecttJAutoProxyCreator的父類AbstractAutoProxyCreator實現了bean後置處理器和BeanfactoryAware。post
分別在父類ProxyProcessorSupport 204行和241行打斷點,由於都是和建立bean的相關方法。ui
父類AbstractAdvisorAutoProxyCreator 以下圖所示打好斷點this
AnnotationAwareAspectJAutoProxyCreator 75行打好斷點
調試開始:
查看調用棧:
postProcessBeforeInstantiation()即實例化以前的後置處理,通過屢次調試咱們會發現每建立一個bean以前都會通過這裏。
通過屢次調試分析以下結果:
//AbstractAutoProxyCreator.java public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { //爲給定的bean類和bean名稱構建一個緩存鍵。 Object cacheKey = getCacheKey(beanClass, beanName); if (beanName == null || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { //代理bean標記 this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } // Create proxy here if we have a custom TargetSource. // Suppresses unnecessary default instantiation of the target bean: // The TargetSource will handle target instances in a custom fashion. //若是定義了TargetSource 在此處建立代理 if (beanName != null) { TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { this.targetSourcedBeans.add(beanName); Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } } return null; }
咱們看一下getCacheKey()
//爲給定的bean類和bean名稱構建一個緩存鍵。 protected Object getCacheKey(Class<?> beanClass, String beanName) { if (StringUtils.hasLength(beanName)) { return (FactoryBean.class.isAssignableFrom(beanClass) ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName); } else { return beanClass; } }
以下例子:
返回一個bean名稱是demo的對象。
//AbstractAutoProxyCreator.java /** * Create a proxy with the configured interceptors if the bean is * identified as one to proxy by the subclass. * @see #getAdvicesAndAdvisorsForBean */ //若是bean被子類標識爲代理,則使用配置的攔截器建立代理 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
此方法是bean初始化的時候被調用的。
以下調用棧:
bean初始化
初始化後應用bean處理
咱們進入wrapIfNecessary()方法:
/** * Wrap the given bean if necessary, i.e. if it is eligible for being proxied. * @param bean the raw bean instance * @param beanName the name of the bean * @param cacheKey the cache key for metadata access * @return a proxy wrapping the bean, or the raw bean instance as-is */ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (beanName != null && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. //子類是否標記代理 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; }
上述代碼大概意思是:若是有bean被子類bean作了代理在這裏建立建立bean代理。
調試源碼詳見地址:
https://github.com/dakele895/...