1. 程式人生 > >spring配置日誌切面,實現系統操作日誌記錄

spring配置日誌切面,實現系統操作日誌記錄

//做系統是經常會遇到的情況之一,對系統操作日誌存表記錄

下面給出下例子

需要注意的是,日誌通常資料量會很大,建議已每個人月一張表,或者其他方式分表

例如:logs_2012_1

            logs_2012_2

            logs_2012_3

這樣的形式。

需要引入的jar包

至少得有aop和切面包

1,日誌切面類

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;
import org.aspectj.lang.ProceedingJoinPoint;

import com.opensymphony.xwork2.ActionContext;

/**
 * 日誌記錄儀
 */
public class Logger {
	private LogService logService ;
	
	//注入logService
	public void setLogService(LogService logService) {
		this.logService = logService;
	}


	/**
	 * 記錄日誌 
	 */
	public Object record(ProceedingJoinPoint pjp){
		Log log = new Log();
		try {
			ActionContext ac = ActionContext.getContext();
			//operator
			if(ac != null){
				HttpServletRequest req = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
				if(req != null){
					User user = (User) req.getSession().getAttribute("user");
					if(user != null){
						log.setOperator("" + user.getId() + ":" + user.getEmail());
					}
				}
			}
			
			//operName,方法名
			String methodName = pjp.getSignature().getName();
			log.setOperName(methodName);
			
			//operParams,方法引數列表
			Object[] args = pjp.getArgs();
			log.setOperParams(StringUtil.arr2Str(args));
			
			//呼叫目標物件的方法
			Object ret = pjp.proceed();
			
			//operResult,成功
			log.setOperResult("success");
			
			//resultMsg,結果訊息
			if(ret != null){
				log.setResultMsg(ret.toString());
			}
			return ret ;
		} catch (Throwable e) {
			log.setOperResult("failure") ;
			log.setResultMsg(e.getMessage());
		}
		finally{
			logService.saveEntity(log);//儲存日誌的service方法
		}
		return null ;
	}
}


2,spring配置檔案中寫法


<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xmlns:context="http://www.springframework.org/schema/context" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:aop="http://www.springframework.org/schema/aop" 

xmlns:cache="http://www.springframework.org/schema/cache" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
http://www.springframework.org/schema/aop 

http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
http://www.springframework.org/schema/cache 
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd ">
	

	<!-- logger 將日誌切面類的完整路徑配置進來-->
	<bean id="logger" class="cn.itcast.surveypark.advice.Logger">
                	<!-- 注入切面中需要的資源-->
		<property name="logService" ref="logService" />
	</bean>
	
	<!-- aop事務配置 -->
	<aop:config>
 		
		<!-- 日誌切入點 這裡一定要注意,要把插入日誌操作的service排除(and !bean(logService),
			不然後形成死迴圈,因為日誌操作類本身也是在進行寫操作 -->
		<aop:pointcut expression="(execution(* *..*Service.save*(..))
					or execution(* *..*Service.update*(..))
					or execution(* *..*Service.delete*(..))
					or execution(* *..*Service.batch*(..))
					or execution(* *..*Service.new*(..))) and !bean(logService)"id="loggerPointcut" />
		
		<!-- 配置日誌切面 配置order="1"是為了讓日誌切面最先執行-->
		<aop:aspect id="loggerAspect" ref="logger" order="1">
			<aop:around method="record" pointcut-ref="loggerPointcut" />
		</aop:aspect>
	</aop:config>
</beans>