一、导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
二、定义自定义注解
@Target(作用在类、字段或方法)
@Rentention(一般选Runntime)
@Retention(RetentionPolicy.RUNTIME)//定义注解的使用范围,编译时,还是运行时。。。
@Target(ElementType.METHOD)//定义注解用在哪里class,method。。。
public @interface Login {
String value() default "";
}
三、注解贴在需要的地方
四、切点表达式 拿注解
作用域 | 切点表达式 | 切点表达式 | |
作用在字段上 | get | ||
作用在方法上 | @annotation 只能用于选择带有特定注解的方法作为连接点 |
而execution 则可以根据更多的方法特征进行匹配。比如参数、方法名 |
|
作用在类上 | within |
@Around、@Before和@AfterReturning 是方法级别的三个注解。
其中@Around是在方法执行前后,如果方法执行失败了,可以捕捉异常,自己处理,或者抛出。如果抛出,则不再执行后续代码。
@Before在方法执行前
@AfterReturning 是在方法成功返回后(如果执行失败,抛异常,不执行这个切面方法)
以下以自定义注解,做全局日志记录为例 ,展示作用在方法上的注解,的@Around使用形式。
@Aspect
@Component
public class SystemLogAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(SystemLogAspect.class);
@Around("@annotation(com.example.annotation.SystemLog)")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
SystemLog systemLog = method.getAnnotation(SystemLog.class);
String message = systemLog.value();
Long startTime = System.currentTimeMillis();
Object result;
try {
result = joinPoint.proceed();
} catch (Throwable throwable) {
throw throwable;
} finally {
Long endTime = System.currentTimeMillis();
long time = endTime - startTime;
LOGGER.info("[SystemLog] {}.{}: {}ms",
joinPoint.getTarget().getClass().getName(),
method.getName(), time);
}
return result;
}
}