本次实现,是基于注解做的切面
先定义好注解
不了解自定义注解可以参考之前文章:juejin.cn/post/684790…
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyInterface {
}
定义切面
@Aspect
@Component
// 这两个注解不能丢,aspect注解代表为切面,Componet注解代表被spring bean装配
public class MyAspect {
// @annotation用于匹配方法上拥有指定注解的情况,输入注解的限定名称
// 在需要感知注解参数的情况下,也可以这么使用
// @Pointcut("@annotation(param)")
// private void mytest(MyInterface param) {}
@Pointcut("@annotation(com.test.MyInterface)")
private void mytest() {
}
// 需要感知切点参数、注解参数的情况可以这么使用
/* @AfterReturning(value = "mytest(param)", argNames = "joinPoint,param")
public Object doAfterReturn(ProceedingJoinPoint joinPoint, MyInterface param) throws Throwable {
// 注解的value值为param.value()
// 定义注解的方法入参为: JacksonUtils.toJson(joinPoint.getArgs()));
}*/
@AfterReturning(value = "mytest()")
public void doAfterReturn() {
// 引入切点 方法执行后处理什么
....
log.info("方法结束,我开始执行了");
}
@AfterThrowing(value = "reportDatahub()")
public void doAfterThrowing() {
// 引入切点后 遇到抛异常之后处理什么
...
log.info("方法抛异常了,我开始执行了");
}
}
引入切点
@MyInterface
public void test() {
...
log.info("执行代码");
}
效果
如果test方法执行正常,则打印如下:
执行代码
方法结束,我开始执行了
如果test方法抛异常了,则打印如下:
执行代码
方法抛异常了,我开始执行了
总结
实现aop的通知类型、切点表达式、切点注入方式还有很多种,这里不一一列举,大家有需要时可以自行查阅相关资料,重要的是动手实践跑一下程序,就能体会到aop的奥秘了。