前言
最近项目已经开发完成,但发现需要加用户操作日志,如果返回去加也不太现实,所以使用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