How does spring annotation @Aspect for spring source analysis work?

AOP (Aspect Orient Programming), Aspect Orient Programming, is a supplement to OOP. Object-oriented programming considers the structure of the program from a static point of view, and aspect-oriented programming considers the running process of the program from a dynamic point of view.

AOP bottom layer is realized by dynamic proxy mode. There are two kinds of agents: JDK dynamic agent and CGLIB dynamic agent. The dynamic proxy of JDK is interface-oriented. CGLIB can realize both interface and no interface. (For those who are not familiar with dynamic agents, see my introduction to dynamic agents)

Aspect-oriented programming is to encapsulate cross-business logic into Aspects, and use the function of AOP container to implant Aspects into the main business logic. The so-called cross-business logic refers to: generic, unrelated to the main business logic, such as security checks, transaction logs and so on.

@ Aspect can use the tangent function to define the tangent point. We can also use logical operators to check the tangent point to get the compound tangent point. In order to reuse the tangent point in the tangent plane, we can also name the tangent point so that the defined tangent point can be referenced elsewhere. When a join point matches multiple tangents, the weaving order needs to be considered. In addition, an important issue is how to enhance the information of accessing the context of the join point.

1,@Aspect

In xml definition: <aop:aspectj-autoproxy/>,
It is defined at http://www.spring framework.org/schema/aop/spring-aop-3.0.xsd

- <xsd:element name="aspectj-autoproxy">
- <xsd:annotation>
- <xsd:documentation source="java:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator">
- <![CDATA[ 
    Enables the use of the @AspectJ style of Spring AOP.

  ]]> 
  </xsd:documentation>
  </xsd:annotation>
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="include" type="includeType" minOccurs="0" maxOccurs="unbounded">
- <xsd:annotation>
- <xsd:documentation>
- <![CDATA[ 
    Indicates that only @AspectJ beans with names matched by the (regex)
    pattern will be considered as defining aspects to use for Spring autoproxying.

  ]]> 
  </xsd:documentation>
  </xsd:annotation>
  </xsd:element>
  </xsd:sequence>
- <xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
- <xsd:annotation>
- <xsd:documentation>
- <![CDATA[ 
    Are class-based (CGLIB) proxies to be created? By default, standard
    Java interface-based proxies are created.

  ]]> 
  </xsd:documentation>
  </xsd:annotation>
  </xsd:attribute>
- <xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
- <xsd:annotation>
- <xsd:documentation>
- <![CDATA[ 
    Indicate that the proxy should be exposed by the AOP framework as a
    ThreadLocal for retrieval via the AopContext class. Off by default,
    i.e. no guarantees that AopContext access will work.

  ]]> 
  </xsd:documentation>
  </xsd:annotation>
  </xsd:attribute>
  </xsd:complexType>
  </xsd:element>

1.1 registration

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
The inheritance relationship is as follows:

1.2 Analytical Process

AspectJAutoProxyBeanDefinitionParser.java#parse() method

    public BeanDefinition parse(Element element, ParserContext parserContext) {
        AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
        extendBeanDefinition(element, parserContext);
        return null;
    }

Registration process:

 public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
            ParserContext parserContext, Element sourceElement) {

        BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
                parserContext.getRegistry(), parserContext.extractSource(sourceElement));
        useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
        registerComponentIfNecessary(beanDefinition, parserContext);
    }

Call the implementation class:

    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }

1.3 Specific implementation class: AbstractAutoProxyCreator's postProcessAfterInitialization() method

DefaultAopProxyFactory#createAopProxy() method

@Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
            if (targetClass.isInterface()) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

jdk's own proxy is used by default, and there is also a cglib mode.

Keywords: Java Programming Spring Attribute JDK

Added by jgp4 on Tue, 04 Jun 2019 03:56:48 +0300