SpringBoot使⽤SpringAOP实现⽇志审计等功能
项⽬当中需要对⽤户操作菜单的⾏为记录⽇志,⽤SpringAOP写了个⼤概实现,切点是采⽤注解的⽅式,⽤包名的⽅式虽然也可以达到相同的效果,但是不如注解⽅式灵活⽅便。
不多说,直接上代码,此处只是简单写写实现原理。
⼯程⽬录:
<!-- 热部署模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional><!-- 这个需要为 true 热部署才有效 -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring-boot aop依赖配置引⼊ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
注解:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Action {
String description() default "no description";
}
Controller类:
/**
* @auther: gaopeng
*/
@RestController
public class AspectController {
/**
springboot aop* ⾛切⾯
* @return
*/
@GetMapping("/test")
@Action(description = "执⾏了test操作菜单")
public String test(){
return "method return";
}
/**
* 不⾛切⾯
*/
@GetMapping("/test1")
private void test1(){
}
/**
* ⾛切⾯,抛异常
*/
@GetMapping("/throws")
@Action(description = "执⾏了throws菜单但是抛了异常")
public void throwsException(){
throw new RuntimeException();
}
}
切⾯类:
/**
* @auther: gaopeng
*/
@Aspect
@Component
public class TestAspect {
/**
* 切⼊点
*/
// 此处的切点是注解的⽅式,也可以⽤包名的⽅式达到相同的效果
/
/@Pointcut("execution(public * com.st.controller.*.*(..))")
@Pointcut("@annotation(com.st.annotation.Action)")
public void execute(){
}
/**
* 前置通知
* @param joinPoint
*/
@Before(value ="execute()")
public void Before(JoinPoint joinPoint) {
System.out.println("执⾏⽅法之前");
}
/**
* 环绕通知
* @param proceedingJoinPoint
* @return
*/
@Around(value ="execute()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("环绕通知开始");
try {
System.out.println("执⾏⽅法:" + Signature().getName()); MethodSign
ature signature =(MethodSignature) Signature(); Action action = Method().getAnnotation(Action.class);
System.out.println("菜单="+action.description());
Object object = proceedingJoinPoint.proceed();
System.out.println("环绕通知结束,⽅法返回:" + object);
return object;
} catch (Throwable e) {
System.out.println("执⾏⽅法异常:" + e.getClass().getName());
return null;
}
}
/**
* 后置通知
* @param joinPoint
*/
@After(value ="execute()")
public void After(JoinPoint joinPoint) {
System.out.println("执⾏⽅法之后");
}
/**
* 后置通知,带返回值
* @param obj
*/
@AfterReturning(pointcut = "execute()",returning = "obj")
public void AfterReturning(Object obj) {
System.out.println("执⾏⽅法之后获取返回值:"+obj);
}
/**
* 后置通知,异常时执⾏
* @param e
*/
@AfterThrowing(throwing = "e",pointcut = "execute()")
public void doAfterThrowing(Exception e) {
System.out.println("执⾏⽅法异常:"+e.getClass().getName());
}
}
运⾏结果:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论