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; }