The Spring AOP

This is the 21st day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

At the heart of Spring are Inversion of Control (IoC) and Aspect Oriented (AOP)

Now that we’ve looked at IOC, let’s see what AOP is!

The concept of AOP

AOP (Aspect Oriented Programming) means: section-oriented Programming, through pre-compilation and runtime dynamic proxy to achieve unified maintenance of program functions of a technology. AOP is a continuation of OOP, a hot topic in software development, and an important content in Spring framework. It is a derivative paradigm of functional programming. Using AOP, each part of the business logic can be isolated, thus reducing the degree of coupling between each part of the business logic, improving the reusability of the program, and improving the efficiency of development.

Why is Spring a one-stop lightweight open source framework? JavaEE development can be divided into three layers of architecture, and Spring provides different solutions for each layer of JavaEE architecture.

• WEB layer: SpringMVC

• Business layer: IoC for Spring

• Persistence layer: Spring’s JDBCTemplate(Spring’s JDBC template, ORM template used to integrate other persistence layer frameworks)

The Spring AOP module provides interceptors to intercept an application, for example, when executing a method, you can add additional functionality before or after the method is executed.

The diagram below:

In our development, the DAO, Service, Controller, and View layers can all be considered as a section, with sections between objects, methods, and modules. * * we don’t change under the condition of the source code, the execution of a method in an aspect, in the later development of want to add some functionality, cost changes in the source code is too large, then we can through the point expression, specify the interceptor which classes which methods, to the specified class at run time into plane class code. This is aspect oriented programming. The following figure is also an implementation flow.

Note: AOP is not a technology, but actually a programming idea.

Second, AOP composition

A technique for dynamically adding functionality to a program without modifying the source code through precompilation and runtime dynamic proxies.

The main functions are: logging, performance statistics, security control, transaction handling, exception handling and so on.

Before we start working with AOP, let’s familiarize ourselves with AOP concepts and terminology. These terms are not specific to Spring, but are AOP related.

item describe
Aspect (Aspect) A module has a set of APIs that provide crosscutting requirements. For example, a logging module will be called by an AOP aspect for logging. An application can have any number of aspects, depending on the requirements.
Join point It represents a point in your application where you can plug in AOP aspects. You could also say that it is in a real application where one of the operations will use the Spring AOP framework.
Advice (Advice) This is the method of execution before or after the actual action. This is the code that is actually called through the Spring AOP framework during program execution.
Pointcut (cut short) This is a set of one or more join points where notifications should be executed. You can specify pointcuts using expressions or patterns as we will see in the AOP example.
Introduction References allow you to add new methods or attributes to an existing class.
Target object An object notified by one or more aspects. This object is always a proxied object. Also known as notified objects.
Weaving (Weaving) Weaving connects aspects to other application types or objects and creates a notified object. This can be done at compile time, class load time, and run time.

Type of notification

In SpringAOP, Advice allows you to use the following five types of Advice:

notice describe
Pre notice Execute notifications before a method executes.
The rear notice After a method is executed, notifications are executed regardless of the result.
Notification of return After a method is executed, notifications can only be executed if the method completes successfully.
Notification when an exception is thrown After a method is executed, notifications can only be executed if the method exits and throws an exception.
Surrounding the notification Notifications are performed before and after the proposed method invocation.

Three, the implementation of AOP

  • Implemented through the Spring API
  • Custom classes to implement Aop
  • Through annotations

Project Structure:

Need to import an AOP weave into dependency package!

<! -- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.9.4</version>
</dependency>
Copy the code

1.Implemented through the Spring API

Writing a business interface

public interface UserService {
   public void add(a);
   public void delete(a);
   public void update(a);
   public void search(a);
}
Copy the code

Write the business interface implementation class

public class UserServiceImpl implements UserService{
    @Override
    public void add(a) {
        System.out.println("Xiaoqian increase user");
    }
    @Override
    public void delete(a) {
        System.out.println("Xiaoqian delete user");
    }
    @Override
    public void update(a) {
        System.out.println("Xiaoqian update user");
    }
    @Override
    public void search(a) {
        System.out.println("Xiaoqian query user"); }}Copy the code

Write two logging enhancement classes

Lead to enhance

public class BeforeLog implements MethodBeforeAdvice {

    //method: the method of the target Object to be executed. Objects: the parameters of the called method
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println( o.getClass().getName() + "The" + method.getName() + "Method is executed."); }}Copy the code

The rear enhancement

public class AfterLog implements AfterReturningAdvice {
    / / the returnValue return values
    //method Specifies the method to be called
    //args is the argument to the object of the called method
    //target Specifies the target object to be called
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("Executed." + target.getClass().getName()
                +"The"+method.getName()+"Method."
                +"Return value:"+returnValue); }}Copy the code

Write the applicationContext. XML


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

    <! Registered bean -- -- -- >
    <bean id="userService" class="com.mq.service.UserServiceImpl"/>
    <bean id="before" class="com.mq.log.AfterLog"/>
    <bean id="afterLog" class="com.mq.log.BeforeLog"/>


    <! Aop configuration requires importing AOP constraints -->
    <aop:config>
        <! Pointcut expression: expression matches the method to execute -->
        <aop:pointcut id="pointcut" expression="execution(* com.mq.service.UserServiceImpl.*(..) )"/>
        <! -- Implementation surround; Advice-ref execute method.pointcut-ref pointcut -->
        <aop:advisor advice-ref="before" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>
</beans>
Copy the code

We’re defining pointcuts by class

2. The use of execution expressions:

See this blog execution expression test class for more details

public class Text {

    @Test
    public void test(a){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) context.getBean("userService"); userService.search(); }}Copy the code

Results:

2,Custom classes to implement Aop

Make a custom DiypointCut and write the method you want to execute

public class DiypointCut {

    public void before(a){
        System.out.println("=========before method execution before ========");
    }
    public void after(a){
        System.out.println("=========after method executed ========="); }}Copy the code

Write the applicationContext. XML

 <! -- Second way to customize implementation -->
    <! Registered bean -- -- -- >
    <bean id="userService" class="com.mq.service.UserServiceImpl"/>
    <bean id="diy" class="com.mq.diy.DiypointCut"/>
    <! Aop configuration -->
    <aop:config>
        <! Second way: use AOP's tag implementation -->
        <aop:aspect ref="diy">
            <aop:pointcut id="diyPonitcut" expression="execution(* com.mq.service.UserServiceImpl.*(..) )"/>
            <aop:before pointcut-ref="diyPonitcut" method="before"/>
            <aop:after pointcut-ref="diyPonitcut" method="after"/>
        </aop:aspect>
    </aop:config>
Copy the code

The test class

public class Text {

    @Test
    public void test(a){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) context.getBean("userService"); userService.delete(); }}Copy the code

Results:

3,Annotations to realize

Write AnnotationPointcut annotation implementation of the enhanced class

@Aspect  // mark this class as an aspect
public class AnnotationPointcut {

    @Before("execution(* com.mq.service.UserServiceImpl.*(..) )"
    public void before(a){
        System.out.println("--------- method before execution ---------");
    }
    @After("execution(* com.mq.service.UserServiceImpl.*(..) )"
    public void after(a){
        System.out.println("--------- method executed after ---------");
    }

    // In wrap enhancement, we can give a parameter that represents the point at which we want to get the processing cut
    @Around("execution(* com.mq.service.UserServiceImpl.*(..) )"
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("Around the front");
        System.out.println("Signature."+jp.getSignature());
        // Execute the target method proceed
        Object proceed = jp.proceed();
        System.out.println("Around the back"); System.out.println(proceed); }}Copy the code

In the Spring configuration file, register the beans and add configurations that support annotations

    <! Third way: Annotation implementation -->
    <bean id="annotationPointcut" class="com.mq.diy.AnnotationPointcut"/>
    <bean id="userService" class="com.mq.service.UserServiceImpl"/>
    <! <aop:aspectj-autoproxy poxy-target-class="true"/> -- proxy-target-class ="true"/> Represents weaving enhancement using CGLib dynamic proxy technology. But even if proxy-target-class is set to false, Spring will automatically use CGLib dynamic proxies if the target class does not declare an interface. -->
	 <! -- Enable annotation support -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
Copy the code

The test class:

public class Text {

    @Test
    public void test(a){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) context.getBean("userService"); userService.add(); }}Copy the code

Results:

Learning must read more official documents, read more source code, understand the underlying principle is how to achieve, today’s learning!