1. 程式人生 > >aop:aspectj-autoproxy 標籤解析

aop:aspectj-autoproxy 標籤解析

1.標籤解析對應的handler

http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
對應的解析類如下
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());

2.解析過程

@Override
public BeanDefinition parse(Element element, ParserContext parserContext) 
{ AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element); extendBeanDefinition(element, parserContext); return null; }
往下看
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
   return 
registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
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);

最重要的是註冊了AnnotationAwareAspectJAutoProxyCreator類AnnotationAwareAspectJAutoProxyCreator實現了介面BeanPostProcessor
/**
 * Create a proxy with the configured interceptors if the bean is
 * identified as one to proxy by the subclass.
 * @see #getAdvicesAndAdvisorsForBean
 */
@Override
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產生一個代理物件。我們再看AnnotationAwareAspectJAutoProxyCreator類,覆蓋了findCandidateAdvisors方法
@Override
protected List<Advisor> findCandidateAdvisors() {
   // Add all the Spring advisors found according to superclass rules.
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   return advisors;
}

我們看this.aspectJAdvisorsBuilder.buildAspectJAdvisors()

if (this.advisorFactory.isAspect(beanType)) {
   aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
   if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
      MetadataAwareAspectInstanceFactory factory =
            new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
      if (this.beanFactory.isSingleton(beanName)) {
         this.advisorsCache.put(beanName, classAdvisors);
}
      else {
         this.aspectFactoryCache.put(beanName, factory);
}
      advisors.addAll(classAdvisors);
}
   else {
      // Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
         throw new IllegalArgumentException("Bean with name '" + beanName +
               "' is a singleton, but aspect instantiation model is not singleton");
}
      MetadataAwareAspectInstanceFactory factory =
            new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
      this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}

如果這個beanType有Aspect註解則從這個類中提取Advisor。我們看下面提取Advisor的過程。

this.advisorFactory.getAdvisors(factory)
List<Advisor> advisors = new LinkedList<Advisor>();
for (Method method : getAdvisorMethods(aspectClass)) {
   Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
   if (advisor != null) {
      advisors.add(advisor);
}
}
@Override
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
      int declarationOrderInAspect, String aspectName) {

   validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
   if (expressionPointcut == null) {
      return null;
}

   return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
         this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}