這個東西怎麼做:spring aop 面向切面編程 如何來做一個強大的日志記錄功能模板;
昨天經理把這個任務交給我,讓我為公司現在的項目加上一個詳細的日志記錄功能模板,對所有的操作,至少是增刪改運作進行一個記錄,其要記錄操作者,以及執行的方法,IP,以及操作的方法的參數.
我以前做過類似的功能,不過是在filter裡做的,通過filter來檢查action請求,記錄請求中的參數及action名字.但是今天公司這個是要求用spring aop來做,這樣就可以在spring裡對要進行的日志記錄方法進行一個配置.而且這樣也就可以無縫集成到現有的系統中去了.
不過,很郁悶的是,我還沒用這樣做過,或者類似的功能.
==========================
哈哈,很爽,居然讓我做好了.
其實也很簡單,使用AOP的@AspectJ來做就可以了,方法步驟如下:
第一:>>在spring的配置文件裡增加以下配置
<!-- 支持 @AspectJ 標記-->
<aop:aspectj-autoproxy />
如果發現插入後,eclipse提示這行有錯誤,那可能是你的spring配置有問題,你對照一下我的spring裡的beans的頭:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
default-autowire="byName" default-lazy-init="true">
關於spring和AOP及@aspectj配置可以參考一下我收藏的以下文章
基於@AspectJ配置Spring AOP之一==>http://www.busfly.cn/csdn/post/700.html
Spring 2.0的新特性之@AspectJ==>http://www.busfly.cn/csdn/post/699.html
AspectJ如何實現AOP==>http://www.busfly.cn/csdn/post/698.html
Spring 2.0中的AOP實現-aspectj-Advice==>http://www.busfly.cn/csdn/post/693.html
第二:>>配置一下@AspectJ 的bean,這個Bean就是一個普通的java對象bean,按照普通的bean來配置就行了,我的這個處理切面的bean配置如下 (包含了第一步的配置):
<!-- 支持 @AspectJ 標記-->
<aop:aspectj-autoproxy />
<bean id="logAspect" class="com.hs.dolphin.sys.LogAspect">
<!-- 配置要記錄日志的對象及屬性(要監控的方法的第一個參數) 格式: 對象類名(帶路徑全稱).屬性GET方法名 -->
<property name="obj_method">
<map>
<entry key="default">
<map><!-- 默認值,如果沒有指定對象就執行這個 -->
<entry key="getId"><!-- 屬性的get方法名字 -->
<value>id</value><!-- 屬性名字 -->
</entry>
</map>
</entry>
<entry key="com.hs.dolphin.domain.User">
<map>
<entry key="getId"><!-- 屬性的get方法名字 -->
<value>id</value><!-- 屬性名字 -->
</entry>
<entry key="getUserName"><!-- 屬性的get方法名字 -->
<value>userName</value><!-- 屬性名字 -->
</entry>
</map>
</entry>
</map>
</property>
</bean>
第三:>>在這個切點處理bean類裡,在class定義的上一行加上切面定義標簽,如下:
@Aspect
// 切面定義標簽
public class LogAspect {
private UserSession sessionValue; // 當前操作員基本信息
private String userIpAddress; // 當前操作員IP地址
第四:>>定義切點及處理方法
@Pointcut("execution(* *.*.*.service..*.insert*(..)) || execution(* *.*.*.service..*.update*(..)) "
+ "|| execution(* *.*.*.service..*.remove*(..))"
+ "|| execution(* *.*.*.service..*.delete*(..))")
public void insertPointcut() {
}
可以在@Pointcut定義下面的這個函數裡寫上要處理的代碼,也可以進行更多更多大的擴展,我的項目裡就是做了擴展處理,在上面這個函數裡沒添加任何方法處理,而是在後面擴展,也就是所謂的Advice吧,請看下一步
第五:>>Advice擴展處理
@AfterReturning("insertPointcut()")
public void insertLogInfo(JoinPoint joinPoint)
throws Exception{
/*處理代碼,略*/
}
=====================================
好了,完成了,是不是很容易.在第五步的這個方法裡有一個參數,這個參數也許就是切面自己傳進來的,所以你就這樣寫吧,JoinPoint 對象裡可以獲取切面切點的相關信息,如方法名,參數,類路徑,類名等等,這樣我們就可以來記錄操作者進行的操作的詳細信息,比如執行的方法名,其所在的對象類名,操作方法裡帶的所有參數信息,等,再加上自己另外獲取一些信息,比如,當前操作時間,操作用戶,還可以根據以上信息來定義操作類別等等
本文裡源碼下載,只是關鍵的一個spring配置文件和那個bean,其它的文件沒上傳上來.轉載者請將附件上傳到你的服務器上
本文配套源碼