Annotation与SpEL实现系统记录操作日志

先说几句废话吧。最近工作比较混乱,一遍研究着Hadoop,一遍搞着另外一个系统的开发。这段时间,一心想写点技术文章却迟迟没能提笔。今天终于,打开音乐播放器,戴上耳机。享受着宁静的夜晚与指尖跃起的文字。甚至于还想着,什么时候才能有合适的机会回到山东,守在爸妈身边。好了,废话不多说了,开始记录正文。

需求:

系统中的一个模块属于关键区,它所有的操作主要针对修改与删除是要求记录下日志来的。而这个记录的日志并不是像我们把它们打印在log文件里,而是需要标准的记录到数据库中。以便于后来专门日志操作模块的查询。

思考:

当然针对这个需求并不困难,在Service层的每个方法逻辑里添加一段代码专门用来插入到对应的log表中即可。可是,那太丑陋了!也不宜于维护。要是能用Annotation标注在方法头,然后凡是做标注的方法,当它们执行的时候,会将结果和相关信息插入到DB中就好了。针对这个YY需求,我做了如下的设计:

  1. 建立一个Annotation(MyLogger),内容用Spring的SpEL表达式模版。
  2. .增加一个AOP方法级的拦截器,切面就在Service层。拦截所标注MyLogger的Service方法。
  3. 拦截到方法时,根据SpEL表达式模版生成记录内容,记录到DB中。

方案:

MyLogger.java

LoggerInterceptor.java 方法拦截器

 

至于AOP的拦截器配置,我就不贴了。这块资料很多,可以随便Google一下。

看了这些代码,可能你已经懵了,说实话确实有点乱,那我们先看看具体怎么应用呢?

举个简单的例子:

上面的logModel内容就是Spring的SpEL表达式模版语句了,具体语法就不细讲了,我也没有太细的去研究。其中#arg0,#arg1代表这方法的第1,2个参数,当然这个名字是我定义的,方便我调用而已,并不是SpEL的规范。这样在执行SpEL解析后,logModel的内容就变成了XXX:”变量a的值,XXX:变量b的值”。

你的疑问可能来了,要是我需要的变量不在参数里面怎么办?argPlus就是来解决这个问题的。

其中ABC.class在拦截的时候会被Spring取出它的对象,然后放进SpEL解析器,执行它对应的方法后获取你想要的值。可能还会觉得有点不理解,那只能这样,如果你看到这个方案感觉不错,想在你的项目采用并且还没看明白的话,来信问吧。me[at]chenzhiguo.cn ^_^