This article describes using Spring AOP in SpringBoot.

Introduction to the

Introduction of AOP

AOP may be familiar to most developers. It is the abbreviation of Aspect Oriented Programming, which translates into Chinese: Aspect Oriented Programming. The problem may be often mentioned in the interview, it is also a significant feature in the Spring framework, AOP implementation mainly is for the purpose of the business section in the process of extraction, it faces is a step or phase in the process and to obtain low coupling between the parts in the process of logical isolation effect, Probably the most common ones in our development are logging, transaction handling, exception handling, and so on.

AOP is used in SpringBoot

Next, you’ll see how AOP is used in the SpringBoot project.

New project

Create a New SpringBoot project and add AOP dependencies to the POM file. The complete code is as follows:

<? xml version="1.0" encoding="UTF-8"? > <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> < modelVersion > 4.0.0 < / modelVersion > < groupId > com. Dalaoyang < / groupId > < artifactId > springboot_aop < / artifactId > < version > 0.0.1 - the SNAPSHOT < / version > < packaging > jar < / packaging > < name > springboot_aop < / name > <description>springboot_aop</description> <parent> <groupId>org.springframework.boot</groupId> The < artifactId > spring - the boot - starter - parent < / artifactId > < version > 2.0.4. RELEASE < / version > < relativePath / > <! -- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> < project. Reporting. OutputEncoding > utf-8 < / project. Reporting. OutputEncoding > < Java version > 1.8 < / Java version > </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>
Copy the code

Create a plane

A direct use of the section

Create a new logging aspect class. Suppose we need a class to print the logs that need to be printed after the method is entered or executed.

Create a new section class

Create a new class LogAspect and the complete code is as follows:

package com.dalaoyang.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;
import org.aspectj.lang.annotation.*;

@Aspect
@Component
public class LogAspect {
    @Pointcut("execution(public * com.dalaoyang.controller.*.*(..) )")
    public void LogAspect(){}

    @Before("LogAspect()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("doBefore");
    }

    @After("LogAspect()")
    public void doAfter(JoinPoint joinPoint){
        System.out.println("doAfter");
    }

    @AfterReturning("LogAspect()")
    public void doAfterReturning(JoinPoint joinPoint){
        System.out.println("doAfterReturning");
    }

    @AfterThrowing("LogAspect()")
    public void deAfterThrowing(JoinPoint joinPoint){
        System.out.println("deAfterThrowing");
    }

    @Around("LogAspect()")
    public Object deAround(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("deAround");
        returnjoinPoint.proceed(); }}Copy the code

Among them:

  • @Aspect indicates a section class
  • @Component injects the current class into the Spring container
  • The @pointcut Pointcut, where execution is used to use join points of the aspect. Use method: Execution (Method modifiers (optional) return type Method name parameter exception pattern (optional)), can match characters with wildcards, * can match any character.
  • @before is executed Before the method
  • @after is executed After the method
  • Execution of @afterRETURNING after method execution returns a result
  • @afterThrowing is executed when an exception is thrown during method execution
  • The ProceedingJoinPoint () method is the ProceedingJoinPoint method. The above four methods can use JoinPoint, which contains the class name, the method name, and the method name. Information such as parameters.

Use AOP with custom annotations

Create a custom annotation

Create a custom annotation. Creating a annotation is similar to creating an interface. Change interface to @interface.

package com.dalaoyang.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DoneTime {
    String param() default "";
}

Copy the code

Create custom annotation corresponding facets

Create a custom annotation corresponding section, similar to the section in the previous section, which will not be repeated here, the code is as follows:

package com.dalaoyang.aspect;

import com.dalaoyang.annotation.DoneTime;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Date;

@Aspect
@Component
public class DoneTimeAspect {

    @Around("@annotation(doneTime)")
    public Object around(ProceedingJoinPoint joinPoint, DoneTime doneTime) throws Throwable {
        System.out.println("Method start time is :"+new Date());
        Object o = joinPoint.proceed();
        System.out.println("Method end time is :"+new Date()) ;
        returno; }}Copy the code

Creating Controller tests

Create an IndexController to test. These are two normal Web request methods: index uses custom annotations and Index2 does not use custom annotations.

package com.dalaoyang.controller;

import com.dalaoyang.annotation.DoneTime;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class IndexController {

    @GetMapping("/index")
    @DoneTime(param = "IndexController")
    public String index(){
        System.out.println("Method execution");
        return "hello dalaoyang";
    }

    @GetMapping("/index2")
    public String index2(){
        System.out.println("Method 2 execution");
        return "hello dalaoyang"; }}Copy the code

Run the test

Start the project, in your browser to http://localhost:8080/index, the console as follows:

In the browser to http://localhost:8080/index2, the console as follows:

conclusion

This article is a brief introduction to SpringBoot’s use of Spring AOP, although there may be other ways to use it, depending on your situation.

Source code download: elder Yang code cloud