前言
最近項目已經開發完成,但發現需要加用戶操作日志,如果返回去加也不太現實,所以使用springAOP來完成比較合適。下面來一起看看詳細的介紹:
注解工具類:
1
2
3
4
5
6
7
|
@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface LogAnnotation { String operateModelNm() default "" ; String operateFuncNm() default "" ; String operateDescribe() default "" ; } |
切面類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
@Aspect public class MyInterceptor { @Pointcut ( "execution(** com.luchao.spring.test3.service.impl.*.*(..))" ) private void anyMethod(){} //定義一個切入點 @Before ( "anyMethod() && args(name)" ) public void doAccessCheck(String name){ System.out.println(name); System.out.println( "前置通知" ); } @AfterReturning ( "anyMethod()" ) public void doAfter(){ System.out.println( "后置通知" ); } @After ( "anyMethod()" ) public void after(JoinPoint point){ System.out.println( "最終通知" ); } @AfterThrowing ( "anyMethod()" ) public void doAfterThrow(){ System.out.println( "例外通知" ); } @Around ( "anyMethod()" ) public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{ Signature signature = pjp.getSignature(); MethodSignature methodSignature = (MethodSignature)signature; Method targetMethod = methodSignature.getMethod(); // System.out.println("classname:" + targetMethod.getDeclaringClass().getName()); // System.out.println("superclass:" + targetMethod.getDeclaringClass().getSuperclass().getName()); // System.out.println("isinterface:" + targetMethod.getDeclaringClass().isInterface()); // System.out.println("target:" + pjp.getTarget().getClass().getName()); // System.out.println("proxy:" + pjp.getThis().getClass().getName()); // System.out.println("method:" + targetMethod.getName()); Class[] parameterTypes = new Class[pjp.getArgs().length]; Object[] args = pjp.getArgs(); for ( int i= 0 ; i<args.length; i++) { if (args[i] != null ) { parameterTypes[i] = args[i].getClass(); } else { parameterTypes[i] = null ; } } //獲取代理方法對象 String methodName = pjp.getSignature().getName(); Method method = pjp.getSignature().getDeclaringType().getMethod(methodName, parameterTypes); if (method.isAnnotationPresent(LogAnnotation. class )){ System.out.println( "存在1" ); } //獲取實際方法對象,可以獲取方法注解等 Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes()); if (realMethod.isAnnotationPresent(LogAnnotation. class )){ realMethod.getAnnotation(LogAnnotation. class ).operateDescribe(); System.out.println( "存在2" ); } System.out.println( "進入環繞通知" ); Object object = pjp.proceed(); //執行該方法 System.out.println( "退出方法" ); return object; } } |
配置類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@Configurable @EnableAspectJAutoProxy @ComponentScan (basePackages = "com.luchao.spring.test3" ) public class test3Config { @Bean public MyInterceptor myInterceptor(){ return new MyInterceptor(); } @Bean public EncoreableIntroducer encoreableIntroducer(){ return new EncoreableIntroducer(); } } |
服務類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
@Component public class PersonServiceBean implements PersonServer { /** * 保存方法 * @param name */ @LogAnnotation (operateModelNm = "測試方法" , operateFuncNm = "保存方法" ) public void save(String name) { System.out.println( "我是save方法" ); } /** * 更新方法 * @param name * @param id */ public void update(String name, Integer id) { System.out.println( "我是update()方法" ); } /** * 獲取方法 * @param id * @return */ public String getPersonName(Integer id) { System.out.println( "我是getPersonName()方法" ); return "xxx" ; } } |
測試方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@RunWith (SpringJUnit4ClassRunner. class ) @ContextConfiguration (classes = test3Config. class ) public class SpringAOPTest { @Autowired private PersonServer personServer; @Test public void inteceptorTest(){ Encoreable encoreable = (Encoreable)personServer; encoreable.performEncore(); personServer.save( "test" ); } } |
在springAOP切面中使用的是代理,所以直接獲取的是代理對象,不能獲取真實對象的一些信息,如注解等。
1
2
3
|
//獲取代理方法對象 String methodName = pjp.getSignature().getName(); Method method = pjp.getSignature().getDeclaringType().getMethod(methodName, parameterTypes); |
如果要獲取真實對象,獲取注解的信息,可以方便我們進行判斷記錄。
1
2
|
//獲取實際方法對象,可以獲取方法注解等 Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes()); |
這樣就完成了一個簡單的操作日志記錄demo。另外,如果不是講某個方法設置切點,可以ant風格的切點切入方式,設置多個或所有方法。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:http://www.cnblogs.com/lcngu/p/6593190.html