天天看點

springboot注解方式實作aop及正常方式

本文介紹springboot實作aop的兩種方式

首先需要引入對應依賴:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.9.1</version>
        </dependency>
           

在啟動類上面加上注解

其實不加這個注解也可以,aop照樣會生效,我們檢視spring-boot-autoconfigure的依賴,檢視spring.factories檔案會發現以下配置

springboot注解方式實作aop及正常方式

然後檢視AopAutoConfiguration類會發現,當yml沒有對應配置時,預設為true

springboot注解方式實作aop及正常方式

下面展示正常方式實作aop的示例:

/**
 * @Description
 * @Author maruko
 * @Date 2022/11/22 17:04
 * @Version 1.0
 */
@Aspect
@Component
public class AspectTest {

    @Pointcut("execution(* com.zjf.demo.controller.UserController.*(..))||execution(* com.zjf.demo.controller.KafkaController.*(..))")
    public void pointExpression() {

    }

    @Before("pointExpression()")
    public void before(JoinPoint joinPoint) {
//        System.err.println(joinPoint.toString());
//        Object[] args = joinPoint.getArgs();
//        for (Object arg : args) {
//            System.err.println(arg);
//        }

//        System.err.println(joinPoint.getSignature().toLongString());
//        System.err.println(joinPoint.getSignature().toShortString());
//        System.err.println(joinPoint.getSignature().getName());
//        System.err.println(joinPoint.getSignature().toString());
//        System.err.println(joinPoint.getKind());
//        System.err.println(joinPoint.getTarget().toString());
//        System.err.println(joinPoint.getThis().toString());
//        System.err.println(joinPoint.getStaticPart());
//        System.err.println(joinPoint.getSourceLocation());
//        System.err.println(joinPoint.toLongString());
//        System.err.println(joinPoint.toShortString());
        System.err.println("前置通知,方法名為:" + joinPoint.getSignature().getName() + " 參數為:" + Arrays.asList(joinPoint.getArgs()));
    }

//    @After("execution(* com.zjf.demo.controller.UserController.*(..))")
    public void after(JoinPoint joinPoint) {
        System.err.println("後置通知,方法名為:" + joinPoint.getSignature().getName() + " 參數為:" + Arrays.asList(joinPoint.getArgs()));

    }

//    @AfterReturning(pointcut = "execution(* com.zjf.demo.controller.UserController.*(..))", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        System.err.println("傳回通知,方法名為:" + joinPoint.getSignature().getName() + " 參數為:" + Arrays.asList(joinPoint.getArgs()) + " 傳回結果為:" + result);
    }

//    @AfterThrowing(value = "execution(* com.zjf.demo.controller.UserController.*(..))", throwing = "exception")
    public void afterThrowing(JoinPoint joinPoint, Exception exception) {
        System.err.println("異常通知,方法名為:" + joinPoint.getSignature().getName() + " 參數為:" + Arrays.asList(joinPoint.getArgs()) + " 異常為:" + exception);
    }

//    @Around("execution(* com.zjf.demo.controller.UserController.*(..))")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) {

        String methodName = joinPoint.getSignature().getName();

        List<Object> args = Arrays.asList(joinPoint.getArgs());

        Object result = null;
        try {
            //前置通知
            System.err.println("前置通知,方法名為:" + joinPoint.getSignature().getName() + " 參數為:" + Arrays.asList(joinPoint.getArgs()));

            result = joinPoint.proceed();

            //傳回通知
            System.err.println("傳回通知,方法名為:" + joinPoint.getSignature().getName() + " 參數為:" + Arrays.asList(joinPoint.getArgs()) + " 傳回結果為:" + result);
        } catch (Throwable e) {
            // 異常通知
            System.err.println("異常通知,方法名為:" + joinPoint.getSignature().getName() + " 參數為:" + Arrays.asList(joinPoint.getArgs()) + " 異常為:" + e);
            throw new RuntimeException(e);
        }

        //後置通知
        System.err.println("後置通知,方法名為:" + joinPoint.getSignature().getName() + " 參數為:" + Arrays.asList(joinPoint.getArgs()));

        return result;
    }


}
           

注解方式實作如下:

首先定義注解:

@Target(ElementType.METHOD)   //定義注解的使用範圍為方法
@Retention(RetentionPolicy.RUNTIME )
public @interface AopAnnotation {
}
           

示例如下:

@Aspect

@Component

@Order(1)

public class AspectAnnotationTest {

@Pointcut(“@annotation(com.zjf.demo.annotation.AopAnnotation)”)

public void pointExpression() {

}

@Before(“pointExpression()”)

public void before(JoinPoint joinPoint) {

// System.err.println(joinPoint.toString());

// Object[] args = joinPoint.getArgs();

// for (Object arg : args) {

// System.err.println(arg);

// }

// System.err.println(joinPoint.getSignature().toLongString());

// System.err.println(joinPoint.getSignature().toShortString());

// System.err.println(joinPoint.getSignature().getName());

// System.err.println(joinPoint.getSignature().toString());

// System.err.println(joinPoint.getKind());

// System.err.println(joinPoint.getTarget().toString());

// System.err.println(joinPoint.getThis().toString());

// System.err.println(joinPoint.getStaticPart());

// System.err.println(joinPoint.getSourceLocation());

// System.err.println(joinPoint.toLongString());

// System.err.println(joinPoint.toShortString());

System.err.println(“注解方式實作,前置通知,方法名為:” + joinPoint.getSignature().getName() + " 參數為:" + Arrays.asList(joinPoint.getArgs()));

}

}