最近写东西觉得将示例放前面比较好。
代码前置
重点:
- 切面类运用
@Configuration
,@Aspect
注解 - 切面类首要办法运用
@Before, @After, @AfterReturning, @AfterThrowing, @Around
等做切入 - 运用的类需求运用@Resource办法注入才会收效。
@Aspect
@Configuration
public class PrintBeforeMethodAspect {
@Around("@annotation(PrintBeforeMethod)")
public void printBefore(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("before method");
joinPoint.proceed();
System.out.println("after method");
}
}
@Resource
Test testService;
@RequestMapping("/aspect/test")
public Object aspectTest() {
testService.test();
return "履行结束";
}
起因
最近有个需求,需求给体系增加多租户功能,需求用到切面编程,运用到@Aspect, 共享一下
@Aspect介绍
@Aspect注解用于标示一个类为切面类。切面类是用来实现AOP(Aspect Oriented Programming)的重要组成部分。
@Aspect注解会告诉Spring框架,这个类包含切面逻辑,需求进行AOP处理。在注解的类中,能够定义切面办法,实现对其他办法的阻拦和增强。
常用的切面办法有:
- @Before – 在方针办法履行前履行的办法,归于前置增强。
- @After – 在方针办法履行后履行的办法,归于后置增强。
- @AfterReturning -在方针办法正常完成后履行的办法,归于回来增强。
- @AfterThrowing – 在方针办法出现反常后履行的办法,归于反常增强。
- @Around – 能够在方针办法前后履行自定义的办法,实现织入增强。 能够有参数JoinPoint,用于获知织入点的办法签名等信息。
@Aspect注解的运用使得AOP能够针对事务层中的各个办法进行权限操控,性能监控,事务处理等操作,然后提高了体系的层次性和健壮性。
完好的实现样例
我是搭配注解来运用的
自定义注解
package com.kevinq.aspect;
import java.lang.annotation.*;
/**
* @author qww
* 2023/4/15 11:24 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface PrintBeforeMethod {
}
切面,首要程序:(留意,切面类上带有@Configuration 注解)
package com.kevinq.aspect;
//import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
* @author qww
* 2023/4/15 11:27 */
@Aspect
@Configuration
public class PrintBeforeMethodAspect {
@Around("@annotation(PrintBeforeMethod)")
public void printBefore(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("before method");
joinPoint.proceed();
System.out.println("after method");
}
}
调用方式:
增加注解
@Service
public class TestService implements Test{
@Override
@PrintBeforeMethod
public void test() {
System.out.println("履行test办法");
}
}
调用办法
@Resource
Test testService;
@RequestMapping("/aspect/test")
public Object aspectTest() {
testService.test();
return "履行结束";
}
值得留意的是,由于运用的@Configuration来注入,所以需求运用@Resource这种办法来实例化调用,用new TestService()无效。