使用Spring切面编程记录操作行为的日志

来源:互联网 发布:少女时代整容知乎 编辑:程序博客网 时间:2024/05/29 16:57

 项目开发中,有一个需求是这样的:登录用户在增删查改等操作时,需要记录用户每次操作的时间和操作的事件类型,用Spring的AOP编程就可以很容易实现这个需求。

AOP即面向切面的编程(Aspect Oriented Programming ),我们经常说面向切面的编程,但什么是面向切面?这里很多人有不同的理解,网上也有很多不同的答案,但很少有人能理解透彻并通过具体例子来讲解的。

一、配置AOP切面

<!-- 日志切面配置--><aop:config><aop:pointcut id="log" expression="execution(* com.xxx.service.*.*(..))" /><aop:aspect ref="operatorAspect"><aop:around method="recordOperator" pointcut-ref="log"/></aop:aspect> </aop:config>

这个切面配置表明,系统中的所有service包中的类(甚至是子包中的类)所有方法,都可以通过operatorAspect类来进行做切面,这里的execution中的表达式可以上网查看具体的各种含义,operatorAspect类通过注解的方式声明。

@Aspect@Componentpublic class OperatorAspect{}


二、定义operator注解

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Operator {public String operator();}

这个注解可以理解为,凡是使用了这个注解的方法,都可以被代理,其中ElementType、RetentionPolicy等有多种取值,可以自己上网查找。


三、具体的Servie类使用operator注解

    @Operator(operator="增加或更新文本消息")    public void saveTextMessage()    {       ......     }

这里的operator=“增加或更新文本消息”,会被set到Operator注解的参数中。


四、切面类代理save方法

 @After(value = "operator()")        public void recordOperator(ProceedingJoinPoint point) throws Throwable        {            Object[] param = point.getArgs(); // 方法参数列表            long begin = 0L; // 开始时间            long end = 0L;// 结束时间            begin = System.currentTimeMillis();            point.proceed();            end = System.currentTimeMillis();            // String operatorName = SpringSecurityUtil.getCurrentUserName();//操作人            String expend = (end - begin) + ""; // 一共花费多长时间            Signature signature = point.getSignature(); // 返回当前连接点签名            MethodSignature methodSignature = (MethodSignature) signature;            Method method = methodSignature.getMethod();            Operator operator = (Operator) Util.getAnnotation(method, Operator.class);            LogDaily logDaily = new LogDaily(); // 日志            logDaily.setCreateTime(new Date()); // 创建时间            logDaily.setExpendTime(expend); // 执行花费时间            logDaily.setOperatorName(userName); // 操作人            logDaily.setRecordType(""); // 操作类型            logDaily.setDescription(operator.operator());// 操作描述            logDailyService.insertLogDaily(logDaily);        }

这里的@After表明使用的是save方法之后的通知,point对象就把整个操作过程代理了,可以通过这个对象获得save方法的参数、注解的类容(即步骤三中的“增加或更新文本消息”)等信息。



如此一来,使用SpringAOP来做到日志记录的需求就完成了。






0 0