AOP series (two) Spring AOP

I. Introduction

Spring AOP AOP provides a comprehensive solution. Spring Spring AOP and the IOC AspectJ seamlessly integrated with, in order to meet all the needs of AOP consistent in Spring-based application architecture.

Two, SpringBoot Integrated Spring-Aop

Add dependent

maven依赖添加如下
<!--引入SpringBoot的Web模块-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 
<!--引入AOP依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
复制代码

Note: At the conclusion of the introduction of AOP dependencies, do not require additional configuration. The default configuration properties of the AOP, spring.aop.auto property is enabled by default, which means that as long as the introduction of AOP dependency, default has increased @EnableAspectJAutoProxy, no need to increase @EnableAspectJAutoProxy in the program to enable the master class.

Write the code section

Use @Aspect aspect class labels, @Component must be added, so that the injection cut IOC container management class

@Aspect
@Component
@Slf4j
public class TestLog {


@Pointcut("execution(* com.yuntian.example.controller.*.*(..))")
public void testLog() {
}


/**
 * 前置通知,方法执行之前执行
 * @param jp
 */
@Before("testLog()")
public void doBefore(JoinPoint jp) {
    // ...
    log.info("方法执行前:.............");
}

/**
 * 后置通知,方法执行之后执行(不管是否发生异常)
 * @param jp
 */
@After("testLog()")
public void doAfter(JoinPoint jp) {
    // ...
    log.info("方法执行后:.............");
}


/**
 * 返回通知,方法正常执行完毕之后执行
 * @param jp
 */
@AfterReturning("testLog()")
public void doAfterReturning(JoinPoint jp) {
    // ...
    log.info("方法执行后返回通知:.............");
}

/**
 * 异常通知,在方法抛出异常之后执行
 * @param jp
 * @param e
 */
@AfterThrowing(value="testLog()",throwing="e")
public void doAfterThrowing(JoinPoint jp,Exception e) {
    // ...
    log.info("方法执行后异常:.............");
}

}
复制代码

Business code

package com.yuntian.example.controller;

import com.yuntian.example.base.Result;
import com.yuntian.example.entity.dto.OrderDTO;
import com.yuntian.example.entity.vo.OrderVO;
import com.yuntian.example.service.OrderService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author yuntian.
 * @date Created in 18:13 2019/8/7
 * @description
 */
@RestController
@RequestMapping("order")
public class OrderController {


@Resource
private OrderService orderService;


@PostMapping("/createOrder")
public Result createOrder(OrderDTO dto){
   OrderVO orderVO= orderService.createOrder(dto);
    Result<OrderVO> result=new Result<>();
    result.setData(orderVO);
    result.setCode(99);
    return result;
}
}
复制代码

result

See section class that implements the logic at the same time, while there is no intrusion of business code.

Write the code section, use around advice

@Aspect
@Component
@Slf4j
public class TestLogAround {


@Pointcut("execution(* com.yuntian.example.controller.*.*(..))")
public void testLogAround() {
}

/**
 * 使用环绕通知
 * @param pjp
 * @return
 */
@Around("testLogAround()")
public Object doAround(ProceedingJoinPoint pjp){
    Object obj=null;
    try{
        log.info("前置通知:执行之前");
        obj=pjp.proceed();
        log.info("返回通知:执行之后");
    } catch(Throwable e){
        log.info("异常通知:........!");
    }
    return  obj;
}
}
复制代码

result

Write the code section, with custom annotation

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MTransaction {

@AliasFor("transactionManager")
String value() default "";

@AliasFor("value")
String transactionManager() default "";


int timeout() default -1;

boolean readOnly() default false;

Class<? extends Throwable>[] rollbackFor() default {};

String[] rollbackForClassName() default {};

Class<? extends Throwable>[] noRollbackFor() default {};

String[] noRollbackForClassName() default {};
}



@Component
@Slf4j
@Aspect
public class TransactionAspect {

@Pointcut("@annotation(com.yuntian.example.annotation.MTransaction)")
public void transactionAspect() {
}

/**
 * 使用环绕通知
 *
 * @param pjp
 * @return
 */
@Around("transactionAspect()")
public Object doAround(ProceedingJoinPoint pjp) {
    //获得执行方法的类名
    MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
    Method method = methodSignature.getMethod();
    Object[] args= pjp.getArgs();
    Object obj = null;
    try {
        log.info("前置通知:开启事务...");
        MTransaction transaction = method.getAnnotation(MTransaction.class);
        if (transaction != null) {
            log.info("注解信息:" + transaction.value());
        }
        log.info("参数:"+JSON.toJSONString(args));
        obj = pjp.proceed();
        log.info("返回通知:关闭事务...");
    } catch (Throwable e) {
        log.info("异常通知:事务回滚...");
    }
    return obj;
}

}
复制代码

result

Second, the introduction section

Cut point expression

All classes entry point method in the range

 @Pointcut("execution(* com.yuntian.example.controller.*.*(..))")
复制代码

The starting point is annotated method

 @Pointcut("@annotation(com.yuntian.example.annotation.MTransaction)")
复制代码

AspectJ indicator

Indicator description
arg() Restriction point matching the specified type of connection parameters to perform a method
@args() Restriction parameter specifies the connection point matching method of performing annotation annotated
execution() Is the point of attachment for matching method is performed
this() Restriction parameter specifies the connection point matching method of performing annotation annotated
target Limit connection point matching the target object for the specified class type
within() Limit connection point matching the specified type
@within() Limit connection type match the specified injection point marked unlocked (when Spring Aop, marked by the method defined class specified annotation)
@annotation The connection point with the specified restriction matching annotations

JoinPoint usage

Fourth, references

blog.csdn.net/XU906722/ar…

Guess you like

Origin juejin.im/post/5db1a353f265da4d1c699492
AOP