利用spring AOP记录用户操作日志的方法示例
前言
最近项目已经开发完成,但发现需要加用户操作日志,如果返回去加也不太现实,所以使用springAOP来完成比较合适。下面来一起看看详细的介绍:
注解工具类:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public@interfaceLogAnnotation{ StringoperateModelNm()default""; StringoperateFuncNm()default""; StringoperateDescribe()default""; }
切面类:
@Aspect publicclassMyInterceptor{ @Pointcut("execution(**com.luchao.spring.test3.service.impl.*.*(..))") privatevoidanyMethod(){}//定义一个切入点 @Before("anyMethod()&&args(name)") publicvoiddoAccessCheck(Stringname){ System.out.println(name); System.out.println("前置通知"); } @AfterReturning("anyMethod()") publicvoiddoAfter(){ System.out.println("后置通知"); } @After("anyMethod()") publicvoidafter(JoinPointpoint){ System.out.println("最终通知"); } @AfterThrowing("anyMethod()") publicvoiddoAfterThrow(){ System.out.println("例外通知"); } @Around("anyMethod()") publicObjectdoBasicProfiling(ProceedingJoinPointpjp)throwsThrowable{ Signaturesignature=pjp.getSignature(); MethodSignaturemethodSignature=(MethodSignature)signature; MethodtargetMethod=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=newClass[pjp.getArgs().length]; Object[]args=pjp.getArgs(); for(inti=0;i配置类:
@Configurable @EnableAspectJAutoProxy @ComponentScan(basePackages="com.luchao.spring.test3") publicclasstest3Config{ @Bean publicMyInterceptormyInterceptor(){ returnnewMyInterceptor(); } @Bean publicEncoreableIntroducerencoreableIntroducer(){ returnnewEncoreableIntroducer(); } }服务类:
@Component publicclassPersonServiceBeanimplementsPersonServer{ /** *保存方法 *@paramname */ @LogAnnotation(operateModelNm="测试方法",operateFuncNm="保存方法") publicvoidsave(Stringname){ System.out.println("我是save方法"); } /** *更新方法 *@paramname *@paramid */ publicvoidupdate(Stringname,Integerid){ System.out.println("我是update()方法"); } /** *获取方法 *@paramid *@return */ publicStringgetPersonName(Integerid){ System.out.println("我是getPersonName()方法"); return"xxx"; } }测试方法:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=test3Config.class) publicclassSpringAOPTest{ @Autowired privatePersonServerpersonServer; @Test publicvoidinteceptorTest(){ Encoreableencoreable=(Encoreable)personServer; encoreable.performEncore(); personServer.save("test"); } }在springAOP切面中使用的是代理,所以直接获取的是代理对象,不能获取真实对象的一些信息,如注解等。
//获取代理方法对象 StringmethodName=pjp.getSignature().getName(); Methodmethod=pjp.getSignature().getDeclaringType().getMethod(methodName,parameterTypes);如果要获取真实对象,获取注解的信息,可以方便我们进行判断记录。
//获取实际方法对象,可以获取方法注解等 MethodrealMethod=pjp.getTarget().getClass().getDeclaredMethod(signature.getName(),targetMethod.getParameterTypes());这样就完成了一个简单的操作日志记录demo。另外,如果不是讲某个方法设置切点,可以ant风格的切点切入方式,设置多个或所有方法。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。