Spring AOP implements source code analysis (1)


The implementation of Spring AOP can be divided into three parts:
1. Register the specific implementation class of the AOP function

2. AOP entry when instantiating ordinary beans

3. AOP cuts into the specific process

 

This article mainly talks about the first part

1. Register the specific implementation class of the AOP function
1.1 Initialize the aop custom label parser AspectJAutoProxyBeanDefinitionParser

      When   the field of aop:aspectj-autoproxy  is read in xml, AspectJAutoProxyBeanDefinitionParser is automatically registered

protected void parseBeanDefinitions (Element root, BeanDefinitionParserDelegate delegate) {
     if (delegate.isDefaultNamespace(root)) {
        if (delegate.isDefaultNamespace(ele)) {
          parseDefaultElement(ele, delegate);
        } else {
          // aop xml configuration enters here, which is divided into two steps
          // 1. Get the parser of aop 2. Use the parser to register the implementation class of aop
          delegate.parseCustomElement(ele);
        }
     } else {
        delegate.parseCustomElement(root);
     }
}
// delegate concrete implementation class BeanDefinitionParserDelegate
public BeanDefinition parseCustomElement(Element ele) {
  return parseCustomElement(ele, null);
 }

public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
  String namespaceUri = getNamespaceURI(ele);
  // The resolve() method will return the handler for the specific processing,
  // handler initialization, that is, the registration of the aop tag parser is done in it
  NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
  // 1.2 will introduce this in detail, call the parse method of the aop parser to complete the registration of the aop functional class bean
  return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
 }
public NamespaceHandler resolve(String namespaceUri) {
  // namespaceUri = "http://www.springframework.org/schema/aop"
  // handlerOrClassName = "org.springframework.aop.config.AopNamespaceHandler"
  Map<String, Object> handlerMappings = getHandlerMappings();
  Object handlerOrClassName = handlerMappings.get(namespaceUri);
  ......
  Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
  NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
  // namespaceHandler is AopNamespaceHandler, call handler to initialize init()
  namespaceHandler.init();
  ......
}
// Final registration processing aop parser AspectJAutoProxyBeanDefinitionParser
AopNamespaceHandler.init(){
    registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
}


1.2 The parser performs parsing. AspectJAutoProxyBeanDefinitionParser is a subclass of BeanDefinitionParser. In the final parse process, its parse() function will eventually register AnnotationAwareAspectJAutoProxyCreator (this class is the function implementation class of aop), and finally the AnnotationAwareAspectJAutoProxyCreator object is converted into a RootBeanDefinition object and enters the Ioc container

// Analytic function in 1.1, continue to analyze
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
  String namespaceUri = getNamespaceURI(ele);
  // The resolve() method will return the handler for the specific processing,
  // handler initialization, that is, the registration of the aop tag parser is done in it
  NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
  // 1.2 will give a detailed introduction to this time, call the parse method of the aop parser, and complete the registration of the aop functional class bean
  return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}

// AspectJAutoProxyBeanDefinitionParser
public BeanDefinition parse(Element element, ParserContext parserContext) {     
  AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);   
  extendBeanDefinition(element, parserContext);
  return null;
}
// AopNamespaceUtils
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
  return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
  // Initialize the bean, aop's implementation class AnnotationAwareAspectJAutoProxyCreator is instantiated,
  // Encapsulated as RootBeanDefinition, enter the Ioc container, the registry is actually DefaultListableBeanFactory
  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;
 }

 

 







 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326323562&siteId=291194637