Record the use of AOP once, and use AOP to complete i18n multi language support integration

Last time

!
forget it. That's all.... I used the enhanced Controller to complete the i18n support before. Later, I thought about whether to try the interceptor and aop respectively, and do it as I say
First, prepare the dependency

rely on

 <!-- aop -->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-aop</artifactId>
 </dependency>
 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.2.47</version>
 </dependency>

Define a slice

We use the @ Aspect annotation to define a class as an Aspect class on the class,
Use @ pointcut (cut expression) to define the pointcut
Use @ around (pointcut) to specify which pointcut a cutting content cuts into
The method has a parameter ProceedingJoinPoint pjp, which represents the method to be cut in. We can use PJP. Processed() to execute the original method. Note that this is to execute the original method. After execution, the original method will be executed directly. If there is a return value, it can be obtained directly;
If the original method is not called, the content of the original method will not be executed. After the original method is called, it will pause waiting for the return stage. Therefore, if the ResponseEntity is used to respond, it will not be resolved to the generic type, and the return value is still ResponseEntity. Unlike the enhanced Controller, the obtained object is the type of the resolved generic type;
Response order... Method response = > AOP = > enhanced controller = > interceptor = > filter

Complete code

/**
 * Define a section print request and return parameter information
 */

@Aspect  // Defined as a section
@Configuration
public class LogRecordAspect {

    private final ResultUtils resultUtils;

    public LogRecordAspect(ResultUtils resultUtils) {
        this.resultUtils = resultUtils;
    }

    private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);

    // Define tangent Pointcut
    @Pointcut("execution(public * com.doria.learnProject.codeStyle.LanguageMapper.*Controller.*(..))")
    public void resultPointcut() {
    }

    /**
     * Section content, code that will come here after triggering the above section
     *
     * @param pjp Method body
     * @return Is the return value of the method
     * @throws Throwable
     */
    @Around("resultPointcut()") // Specify the point of tangency to insert
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        // Gets the requestAttributes bound by the current thread
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        // Strong forward to get Request
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        // Get the request [in fact, I wonder why I don't take the injected HttpServletRequest directly when I see this demo, but I'm very good and don't doubt it. Listen to the boss]
        assert sra != null;
        HttpServletRequest request = sra.getRequest();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String json = JSON.toJSONString(request.getParameterMap());
        logger.info("Request received=>Uri:{},Request mode:{},parameter:{}", uri, method, json);

        // Get the return value of the method. The value of result is the return value
        Object result = pjp.proceed();
        logger.info("End of request=>The return value is:" + JSON.toJSONString(result));

        // Due to special needs, the return value of the parameter needs to be processed here. Here, change the code to the corresponding language and fill in msg
        if (result instanceof Result)
            // Call the language conversion method. The content is about strong conversion, then read the code, and then convert it to msg through i18n and write it to msg
            return resultUtils.languageFormatToResult(result);
        return result;
    }
}

Language filling method

@Autowired
private MessageSource messageSource;

/**
 * Language conversion method
 * @param o Object to be processed
 * @return Processed objects
 */
public Object languageFormatToResult(Object o){
    // Since instanceof is used to determine the specific type before calling the method, we can directly force conversion here
    Result<?> result = (Result<?>) o;
    // Take out the code after forced rotation
    String key = result.getCode().toString();
    // Set msg and use code as key to obtain parameters
    result.setMsg(messageSource.getMessage(key,null, LocaleContextHolder.getLocale()));
    return result;
}

About tangent point and tangent point expression

breakthrough point

You can define a pointcut through this annotation, which can contain no content

// Define tangent Pointcut
    @Pointcut("execution(public * com.doria.learnProject.codeStyle.LanguageMapper.*Controller.*(..))")
    public void resultPointcut() {
    }

Tangent expression

Because the smallest aspect granularity of Spring is to reach the method level, and the execution expression can be used to specify method related components such as method return type, class name, method name and parameter name. In Spring, most business scenarios that need to use AOP only need to reach the method level, so the execution expression is most widely used. The following is the syntax of the execution expression:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)

Here, the question mark indicates whether the current item can have or not. The semantics of each item is as follows:

Modifiers pattern: visibility of methods, such as public and protected;
RET type pattern: the return value type of the method, such as int, void, etc;
Declaring type pattern: the full pathname of the class where the method is located, such as com.spring.Aspect;
Name pattern: method name type, such as buisinessService();
Param pattern: parameter type of the method, such as java.lang.String;
Throws pattern: the type of exception thrown by the method, such as java.lang.Exception;

Pointcut expression explanation

Keywords: Java Spring Boot Back-end AOP

Added by d1223m on Sat, 23 Oct 2021 15:01:16 +0300