欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

利用spring AOP记录用户操作日志的方法示例

程序员文章站 2023-12-11 08:28:46
前言 最近项目已经开发完成,但发现需要加用户操作日志,如果返回去加也不太现实,所以使用springaop来完成比较合适。下面来一起看看详细的介绍: 注解工具类:...

前言

最近项目已经开发完成,但发现需要加用户操作日志,如果返回去加也不太现实,所以使用springaop来完成比较合适。下面来一起看看详细的介绍:

注解工具类:

@retention(retentionpolicy.runtime)
@target(elementtype.method)
public @interface logannotation {
 string operatemodelnm() default "";
 string operatefuncnm() default "";
 string operatedescribe() default "";
}

切面类:

@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;
 }
}

配置类:

@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();
 }
}

服务类:

@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";
 }
}

测试方法:

@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切面中使用的是代理,所以直接获取的是代理对象,不能获取真实对象的一些信息,如注解等。

      //获取代理方法对象
  string methodname = pjp.getsignature().getname();
  method method = pjp.getsignature().getdeclaringtype().getmethod(methodname, parametertypes);

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

       //获取实际方法对象,可以获取方法注解等
  method realmethod = pjp.gettarget().getclass().getdeclaredmethod(signature.getname(), targetmethod.getparametertypes());

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。