Spring AOP (aspect oriented programming)

Posted by Alex-B on Tue, 18 Jan 2022 10:52:43 +0100

Spring AOP (aspect oriented programming)

concept

1. What is AOP?

AOP is the abbreviation of Aspect Oriented Programming, which means Aspect Oriented Programming. It is a technology to realize the unified maintenance of program functions through precompiled mode and runtime dynamic agent.

AOP is the continuation of OOP, a hot spot in software development, an important content in Spring framework, and a derivative paradigm of functional programming. AOP can isolate each part of business logic, reduce the coupling between each part of business logic, improve the reusability of program, and improve the efficiency of development.

2. Role and advantages of AOP

  • Function: during the running of the program, enhance the function of the method without modifying the source code
  • Advantages: reduce duplicate code, improve development efficiency, and easy to maintain

3. What is the underlying implementation of AOP?

In fact, the underlying layer of AOP is implemented through the dynamic proxy technology provided by Spring. During operation, Spring dynamically generates proxy objects through dynamic proxy technology. When the proxy object method is executed, it intervenes to enhance the function, and calls the method of the target object, so as to complete the function enhancement.

4. Dynamic agent technology of AOP

  • JDK agent: dynamic agent technology based on interface
  • cglib proxy: dynamic proxy technology based on parent class

Dynamic agent

As mentioned above, the bottom layer of AOP is realized by two dynamic agent technologies: JDK agent and cglib agent.

The dynamic agent can be preliminarily understood here: Static proxy mode and dynamic proxy mode - Dogeleft - blog Park (cnblogs.com)

These two dynamic agent technologies are introduced below.

Dynamic agent of JDK

Implementation process

1. Target class interface
public interface TargetInterface {
    public void method();	
}
2. Target class
public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("Target running....");
    }
}
3. Dynamic proxy code
    Target target = new Target(); //Create target object
    //Create proxy object
    TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(target.getClass()
    .getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) 
            throws Throwable {
                System.out.println("Pre enhancement code...");
                Object invoke = method.invoke(target, args);
                System.out.println("Post enhancement code...");
                return invoke;
        	}
    	}
    );
4. Method test of calling proxy object
// When calling any method of the interface, the code of the proxy object does not need to be modified
proxy.method();

result:

Dynamic proxy for cglib

Implementation process

1. Target class
public class Target {
    public void method() {
    	System.out.println("Target running....");
    }
}
2. Dynamic proxy code
    Target target = new Target(); //Create target object
    Enhancer enhancer = new Enhancer(); //Create intensifier
    enhancer.setSuperclass(Target.class); //Set parent class
    enhancer.setCallback(new MethodInterceptor() { //Set callback
        @Override
        public Object intercept(Object o, Method method, Object[] objects, 
        MethodProxy methodProxy) throws Throwable {
            System.out.println("Pre code enhancement....");
            Object invoke = method.invoke(target, objects);
            System.out.println("Post code enhancement....");
            return invoke;
        }
    });
    Target proxy = (Target) enhancer.create(); //Create proxy object
3. Method test of calling proxy object
//When calling any method of the interface, the code of the proxy object does not need to be modified
proxy.method();

Related concepts of AOP

The bottom layer of Spring's AOP implementation is to encapsulate the code of the above dynamic agent. After encapsulation, we only need to code the parts that need attention, and complete the method enhancement of the specified goal through configuration.

Important terms related to AOP need to be understood and mastered:

  • Target: the target object of the proxy
  • Proxy: after a class is enhanced by AOP weaving, a resulting proxy class is generated
  • Joinpoint: the so-called connection point refers to those intercepted points. In spring, these points refer to methods, because spring only supports connection points of method types
  • Pointcut: the so-called pointcut refers to the definition of which joinpoints we want to intercept
  • Advice (notification / enhancement): the so-called notification means that what needs to be done after intercepting the Joinpoint is notification
  • Aspect: a combination of pointcuts and notifications (Introductions)
  • Weaving: refers to the process of applying enhancements to the target object to create a new proxy object. spring uses dynamic proxy weaving, while AspectJ uses compile time weaving and class load time weaving

Clear matters for AOP development

1. Contents to be prepared

  • Write core business code (target method of target class)
  • Write a facet class with notifications (enhancement methods) in it
  • In the configuration file, configure the weaving relationship, that is, which notifications are combined with which connection points

2. Content of AOP technology implementation

The Spring framework monitors the execution of pointcut methods. Once it is monitored that the pointcut method is running, the proxy mechanism is used to dynamically create the proxy object of the target object. According to the notification category, the corresponding function of the notification is woven into the corresponding position of the proxy object to complete the complete code logic operation.

3. Which proxy method is used at the bottom of AOP

In spring, the framework will decide which dynamic proxy method to adopt according to whether the target class implements the interface. (JDK or cglib)

Introduction and key points of conceptual knowledge

  • aop: Aspect Oriented Programming
  • The underlying implementation of aop: dynamic agent based on JDK and dynamic agent based on Cglib
  • Key concepts of aop:
    • Pointcut: enhanced method
    • Advice: encapsulates ways to enhance business logic
    • Aspect: pointcut + notification
    • Weaving: the process of combining pointcuts with notifications
  • Clear items for development:
    • Who is the pointcut (pointcut expression configuration)
    • Who is notification (enhancement method in facet class)
    • Weaving pointcuts and notifications into configuration

AOP development based on XML

Quick start process

  1. Import AOP related coordinates
  2. Create target interface and target class (with internal tangent point)
  3. Create facet class (with enhancement method inside)
  4. Leave the object creation rights of the target class and the aspect class to spring
  5. In ApplicationContext Configuring weaving relationships in XML
  6. Test code

1. Import AOP related coordinates

    !--Import spring of context Coordinates, context rely on aop-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.5.RELEASE</version>
    </dependency>
    <!-- aspectj Weaving in -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.13</version>
    </dependency>

2. Create target interface and target class (with internal tangent point)

public interface TargetInterface {
    public void method();
}
public class Target implements TargetInterface {
    @Override
    public void method() {
    	System.out.println("Target running....");
    }
}

3. Create a section class (there are enhancement methods inside)

public class Target implements TargetInterface {
    @Override
    public void method() {
    	System.out.println("Target running....");
    }
}

4. Give the object creation right of the target class and facet class to spring

<!--Configure target class-->
<bean id="target" class="com.itheima.aop.Target"></bean>
<!--Configure facet class-->
<bean id="myAspect" class="com.itheima.aop.MyAspect"></bean>

5. In ApplicationContext Configuring weaving relationships in XML

Import aop namespace

<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

Configure pointcut expressions and pre enhanced weaving relationships

<aop:config>
    <!--quote myAspect of Bean Is a tangent object-->
    <aop:aspect ref="myAspect">
        <!--to configure Target of method Method to execute myAspect of before Method pre enhancement-->
        <aop:before method="before" pointcut="execution(public void 
            com.itheima.aop.Target.method())"></aop:before>
    </aop:aspect>
</aop:config>

6. Test code

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
        @Autowired
        private TargetInterface target;
        @Test
        public void test1(){
        target.method();
    }
}

7. Test results

Detailed explanation of XML configuration AOP

Writing of tangent point expression

Expression syntax:

execution([Modifier ] Return value type package name.Class name.Method name(parameter))
  • The access modifier can be omitted
  • The returned value type, package name, class name and method name can be represented by an asterisk *
  • A point between the package name and the class name Represents the class under the current package, two points Represents the classes under the current package and its sub packages
  • A point between the package name and the class name Represents the class under the current package, two points Represents the classes under the current package and its sub packages

example:

execution(public void com.itheima.aop.Target.method())
execution(void com.itheima.aop.Target.*(..))
execution(* com.itheima.aop.*.*(..))
execution(* com.itheima.aop..*.*(..))
execution(* *..*.*(..))

Type of notification

Configuration syntax for notifications:

<aop:Notification type method="Method name in facet class pointcut="Tangent expression"></aop:Notification type>

Type of notification:

Extraction of tangent expression

Often, the pointcut expression needs to be written repeatedly at each message entry. When multiple enhanced pointcut expressions are the same, the pointcut expression can be extracted. In the enhancement, the pointcut ref attribute is used instead of the pointcut attribute to refer to the extracted pointcut expression.

<aop:config>
	<!--quote myAspect of Bean Is a tangent object-->
    <aop:aspect ref="myAspect">
        <aop:pointcut id="myPointcut" expression="execution(* com.itheima.aop.*.*(..))"/>
        <aop:before method="before" pointcut-ref="myPointcut"></aop:before>
    </aop:aspect>
</aop:config>

Key points of AOP development knowledge based on XML

  • aop weaving configuration

    <aop:config>
        <aop:aspect ref="Cut class>
        <aop:before method="Notification method name pointcut="Tangent expression"></aop:before>
        </aop:aspect>
    </aop:config>
    
  • Notification types: pre notification, post notification, surround notification, exception throw notification, and final notification

  • How to write tangent point expression:

    execution([Modifier ] Return value type package name.Class name.Method name(parameter))
    

Annotation based AOP development

Quick start process

  1. Create target interface and target class (with internal tangent point)
  2. Create facet class (with enhancement method inside)
  3. Leave the object creation rights of the target class and the aspect class to spring
  4. Using annotations to configure weaving relationships in facet classes
  5. Turn on the automatic agent for component scanning and AOP in the configuration file
  6. test

1. Create target interface and target class (with internal tangent point)

public interface TargetInterface {
	public void method();
}
public class Target implements TargetInterface {
    @Override
    public void method() {
    	System.out.println("Target running....");
    }
}

2. Create a section class (there are enhancement methods inside)

public class MyAspect {
    //Pre enhancement method
    public void before(){
    	System.out.println("Pre code enhancement.....");
    }
}

3. Give spring the right to create objects of target class and facet class

@Component("target")
public class Target implements TargetInterface {
    @Override
    public void method() {
    	System.out.println("Target running....");
    }
}

@Component("myAspect")
public class MyAspect {
    public void before(){
    	System.out.println("Pre code enhancement.....");
    }
}

4. Use annotations to configure the weaving relationship in the facet class

@Component("myAspect")
@Aspect
public class MyAspect {
    @Before("execution(* com.itheima.aop.*.*(..))")
    public void before(){
    	System.out.println("Pre code enhancement.....");
    }
}

5. Enable the automatic agent of component scanning and AOP in the configuration file

<!--Component scan-->
<context:component-scan base-package="com.itheima.aop"/>
<!--aop Automatic proxy for-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

6. Test code

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
    @Autowired
    private TargetInterface target;
    @Test
    public void test1(){
    	target.method();
    }
}

7. Test results

Annotation configuration AOP details

Type of annotation notification

Configuration syntax of notification: @ notification annotation ("pointcut expression")

Extraction of tangent expression

Like configuring aop with xml, we can extract Pointcut expressions. The extraction method is to define a method in the cut plane, define the cut point expression on the method with the @ Pointcut annotation, and then refer to it in the enhanced annotation. The details are as follows:

@@Component("myAspect")
@Aspect
public class MyAspect {
    
    @Before("MyAspect.myPoint()")
    public void before(){
    	System.out.println("Pre code enhancement.....");
    }
    
    @Pointcut("execution(* com.itheima.aop.*.*(..))")
    public void myPoint(){}
}

Key points of AOP development knowledge based on annotation

  • Annotate aop development steps
    • Dimension facet classes with @ Aspect
    • Annotate notification method with @ notification annotation
    • Configure aop auto proxy in configuration file
  • The notification annotation type is shown in the figure above

Topics: JavaEE