springAOP记录用户操作日志

  项目已经开发完成,需要加用户操作日志,如果返回去加也不太现实,所以使用springAOP来完成比较合适。

  注解工具类:

1 @Retention(RetentionPolicy.RUNTIME)
2 @Target(ElementType.METHOD)
3 public @interface LogAnnotation {
4     String operateModelNm() default "";
5     String operateFuncNm() default "";
6     String operateDescribe() default "";
7 }

  切面类:

 1 @Aspect
 2 public class MyInterceptor {
 3     @Pointcut("execution(** com.luchao.spring.test3.service.impl.*.*(..))")
 4     private void anyMethod(){}//定义一个切入点
 5 
 6     @Before("anyMethod() && args(name)")
 7     public void doAccessCheck(String name){
 8         System.out.println(name);
 9         System.out.println("前置通知");
10     }
11 
12     @AfterReturning("anyMethod()")
13     public void doAfter(){
14         System.out.println("后置通知");
15     }
16 
17     @After("anyMethod()")
18     public void after(JoinPoint point){
19 
20         System.out.println("最终通知");
21     }
22 
23     @AfterThrowing("anyMethod()")
24     public void doAfterThrow(){
25         System.out.println("例外通知");
26     }
27 
28     @Around("anyMethod()")
29     public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{
30         Signature signature = pjp.getSignature();
31         MethodSignature methodSignature = (MethodSignature)signature;
32         Method targetMethod = methodSignature.getMethod();
33 //        System.out.println("classname:" + targetMethod.getDeclaringClass().getName());
34 //        System.out.println("superclass:" + targetMethod.getDeclaringClass().getSuperclass().getName());
35 //        System.out.println("isinterface:" + targetMethod.getDeclaringClass().isInterface());
36 //        System.out.println("target:" + pjp.getTarget().getClass().getName());
37 //        System.out.println("proxy:" + pjp.getThis().getClass().getName());
38 //        System.out.println("method:" + targetMethod.getName());
39 
40         Class[] parameterTypes = new Class[pjp.getArgs().length];
41         Object[] args = pjp.getArgs();
42         for(int i=0; i<args.length; i++) {
43             if(args[i] != null) {
44                 parameterTypes[i] = args[i].getClass();
45             }else {
46                 parameterTypes[i] = null;
47             }
48         }
49         //获取代理方法对象
50         String methodName = pjp.getSignature().getName();
51         Method method = pjp.getSignature().getDeclaringType().getMethod(methodName, parameterTypes);
52 
53         if(method.isAnnotationPresent(LogAnnotation.class)){
54             System.out.println("存在1");
55         }
56         //获取实际方法对象,可以获取方法注解等
57         Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes());
58 
59         if(realMethod.isAnnotationPresent(LogAnnotation.class)){
60             realMethod.getAnnotation(LogAnnotation.class).operateDescribe();
61             System.out.println("存在2");
62         }
63 
64         System.out.println("进入环绕通知");
65         Object object = pjp.proceed();//执行该方法
66         System.out.println("退出方法");
67         return object;
68     }
69 }

  配置类:

 1 @Configurable
 2 @EnableAspectJAutoProxy
 3 @ComponentScan(basePackages = "com.luchao.spring.test3")
 4 public class test3Config {
 5 
 6     @Bean
 7     public MyInterceptor myInterceptor(){
 8         return new MyInterceptor();
 9     }
10 
11     @Bean
12     public EncoreableIntroducer encoreableIntroducer(){
13         return new EncoreableIntroducer();
14     }
15 }

  服务类:

 1 @Component
 2 public class PersonServiceBean implements PersonServer {
 3 
 4     /**
 5      * 保存方法
 6      * @param name
 7      */
 8     @LogAnnotation(operateModelNm = "测试方法", operateFuncNm = "保存方法")
 9     public void save(String name) {
10         System.out.println("我是save方法");
11 
12     }
13 
14     /**
15      * 更新方法
16      * @param name
17      * @param id
18      */
19     public void update(String name, Integer id) {
20         System.out.println("我是update()方法");
21     }
22 
23     /**
24      * 获取方法
25      * @param id
26      * @return
27      */
28     public String getPersonName(Integer id) {
29         System.out.println("我是getPersonName()方法");
30         return "xxx";
31     }
32 }

  测试方法:

 1 @RunWith(SpringJUnit4ClassRunner.class)
 2 @ContextConfiguration(classes = test3Config.class)
 3 public class SpringAOPTest {
 4 
 5     @Autowired
 6     private PersonServer personServer;
 7 
 8     @Test
 9     public void inteceptorTest(){
10         Encoreable encoreable = (Encoreable)personServer;
11         encoreable.performEncore();
12         personServer.save("test");
13     }
14 }

  在springAOP切面中使用的是代理,所以直接获取的是代理对象,不能获取真实对象的一些信息,如注解等。

1      //获取代理方法对象
2         String methodName = pjp.getSignature().getName();
3         Method method = pjp.getSignature().getDeclaringType().getMethod(methodName, parameterTypes);

  如果要获取真实对象,获取注解的信息,可以方便我们进行判断记录。

1       //获取实际方法对象,可以获取方法注解等
2         Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes());

  这样就完成了一个简单的操作日志记录demo。另外,如果不是讲某个方法设置切点,可以ant风格的切点切入方式,设置多个或所有方法。

原文地址:https://www.cnblogs.com/lcngu/p/6593190.html