1. 程式人生 > >Spring Aop實現簡單日誌記錄

Spring Aop實現簡單日誌記錄

日誌類

package com.jusfoun.estate.log.domain;


import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.*;


import com.itmuch.core.entity.BaseEntity;


@Table(name = "B_LOG")
public class Log  extends BaseEntity implements Serializable {
    private Long id;


    //操作使用者
    @Column(name = "member_id")
    private Long memberId;


    //操作內容
    private String operation;


    //操作型別 1新增2修改3刪除
    @Column(name = "operation_type")
    private Short operationType;


    //
    @Column(name = "login_to")
    private Short loginTo;


    private Date time;


    private String ip;


    @Column(name = "create_time")
    private Date createTime;


    @Column(name = "update_time")
    private Date updateTime;


    @Column(name = "create_id")
    private Long createId;


    @Column(name = "update_id")
    private Long updateId;


    private static final long serialVersionUID = 1L;


    /**
     * @return id
     */
    public Long getId() {
        return id;
    }


    /**
     * @param id
     */
    public void setId(Long id) {
        this.id = id;
    }


    /**
     * @return member_id
     */
    public Long getMemberId() {
        return memberId;
    }


    /**
     * @param memberId
     */
    public void setMemberId(Long memberId) {
        this.memberId = memberId;
    }


    /**
     * @return operation
     */
    public String getOperation() {
        return operation;
    }


    /**
     * @param operation
     */
    public void setOperation(String operation) {
        this.operation = operation;
    }


    /**
     * @return operation_type
     */
    public Short getOperationType() {
        return operationType;
    }


    /**
     * @param operationType
     */
    public void setOperationType(Short operationType) {
        this.operationType = operationType;
    }


    /**
     * @return login_to
     */
    public Short getLoginTo() {
        return loginTo;
    }


    /**
     * @param loginTo
     */
    public void setLoginTo(Short loginTo) {
        this.loginTo = loginTo;
    }


    /**
     * @return time
     */
    public Date getTime() {
        return time;
    }


    /**
     * @param time
     */
    public void setTime(Date time) {
        this.time = time;
    }


    /**
     * @return ip
     */
    public String getIp() {
        return ip;
    }


    /**
     * @param ip
     */
    public void setIp(String ip) {
        this.ip = ip;
    }


    /**
     * @return create_time
     */
    public Date getCreateTime() {
        return createTime;
    }


    /**
     * @param createTime
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }


    /**
     * @return update_time
     */
    public Date getUpdateTime() {
        return updateTime;
    }


    /**
     * @param updateTime
     */
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }


    /**
     * @return create_id
     */
    public Long getCreateId() {
        return createId;
    }


    /**
     * @param createId
     */
    public void setCreateId(Long createId) {
        this.createId = createId;
    }


    /**
     * @return update_id
     */
    public Long getUpdateId() {
        return updateId;
    }


    /**
     * @param updateId
     */
    public void setUpdateId(Long updateId) {
        this.updateId = updateId;
    }
}


service類

package com.jusfoun.estate.log.service;


import java.util.List;


import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Service;


import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.itmuch.core.constants.CodeConstant;
import com.itmuch.core.page.PageInfo;
import com.itmuch.core.page.PageVo;
import com.itmuch.core.service.BaseService;
import com.itmuch.core.util.DozerUtil;
import com.itmuch.core.util.ErrorMsgUtil;
import com.itmuch.core.util.SaltUtil;
import com.itmuch.core.util.SubjectUtil;
import com.itmuch.core.web.converter.Result;
import com.jusfoun.estate.admin.domain.User;
import com.jusfoun.estate.admin.persistence.UserMapper;
import com.jusfoun.estate.admin.vo.PageInfoVo;
import com.jusfoun.estate.admin.vo.UserAdminEditVo;
import com.jusfoun.estate.admin.vo.UserAdminRegVo;
import com.jusfoun.estate.admin.vo.UserVo;
import com.jusfoun.estate.log.domain.Log;
import com.jusfoun.estate.log.persistence.LogMapper;


@Service
public class LogService extends BaseService<LogMapper, Log> {


	private static final int SALT_SIZE = 8;


	/**
	 * 分頁顯示條件查詢
	 * 
	 * @param vo
	 * @param queuryVo
	 * @return
	 */
	public PageInfoVo<UserVo> conditionPageQuery(PageVo vo, UserVo queuryVo) {
		String order = vo.getOrder();


		if ((queuryVo.getRoleIds() != null) && (queuryVo.getRoleIds().size() == 0)) {
			queuryVo.setRoleIds(null);
		}


		PageHelper.startPage(vo.getPage(), vo.getRows(), order);
		List<User> list = this.dao.conditionPageQuery(queuryVo);
		PageInfo<User> info = new PageInfo<User>(list);
		List<UserVo> voList = Lists.newArrayList();


		if ((list != null) && !list.isEmpty()) {


			for (User admin : list) {
				UserVo adminVo = DozerUtil.map(admin, UserVo.class);
				adminVo.setPassword(null);


				// 查詢使用者的角色
				List<Long> roleIds = this.dao.selectRoleIdListByUserId(admin.getId());
				adminVo.setRoleIds(roleIds);
				voList.add(adminVo);
			}


			PageInfoVo<UserVo> infoVo = new PageInfoVo<UserVo>(info.getList(), voList);
			return infoVo;
		}
		return null;
	}


	public PageInfo<UserVo> listAllPaged(PageVo vo) {
		String order = vo.getOrder("CREATE_TIME");
		PageHelper.startPage(vo.getPage(), vo.getRows(), order);


		List<User> list = this.dao.selectAll();
		PageInfo<User> info = new PageInfo<User>(list);


		List<UserVo> voList = Lists.newArrayList();


		if ((list != null) && !list.isEmpty()) {


			for (User admin : list) {
				UserVo adminVo = DozerUtil.map(admin, UserVo.class);
				adminVo.setPassword(null);


				// 查詢使用者的角色
				List<Long> roleIds = this.dao.selectRoleIdListByUserId(admin.getId());
				// 之所以要加這個判斷,是因為easyui 的combobox
				if ((roleIds != null) && roleIds.isEmpty()) {


				}
				adminVo.setRoleIds(roleIds);
				voList.add(adminVo);
			}
			PageInfo<UserVo> pageInfo = new PageInfo<UserVo>(null);
			pageInfo.setTotal(info.getTotal());
			pageInfo.setList(voList);


			return pageInfo;
		}
		return null;


	}


	public void insertLog(Log vo) {


		 this.dao.insertLog(vo);
	}
}


AOP實現類

package com.jusfoun.estate.aop;


import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.Date;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;


import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;


import com.itmuch.core.util.SubjectUtil;
import com.jusfoun.estate.log.domain.Log;
import com.jusfoun.estate.log.service.LogService;


/**
 * 日誌記錄,新增、刪除、修改方法AOP 
 * @author myl
 *
 */
@Aspect 
public class LogAspect {


	 @Resource
	 public LogService logService;
	 
	 /**
	  * 新增操作切入點
	  */
	 @Pointcut("execution(* com.jusfoun.estate.*.service.*.insert*(..))")
	 public void insertServiceCall(){};
	
	 /**
	  * 修改操作切入點
	  */
	 @Pointcut("execution(* com.jusfoun.estate.*.service.*.update*(..))")
	 public void updateServiceCall(){};
	 
	 /**
	  * 刪除操作切入點
	  */
	 @Pointcut("execution(* com.jusfoun.estate.*.service.*.delete*(..))")
	 public void deleteServiceCall(){};
	 
	 /**
	  * 新增操作日誌(後置通知)
	  * @param joinPoint
	  * @param rtv
	  * @throws Throwable
	  */
	 @AfterReturning(value="insertServiceCall()", argNames="rtv", returning="rtv")  
	 public void insertServiceCallCalls(JoinPoint joinPoint, Object rtv) throws Throwable{  
	     
		 //HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 
	     //判斷引數  
	     if(joinPoint.getArgs() == null){//沒有引數  
	         return;  
	     }  
	     String jMethod = joinPoint.getSignature().getName();
	     String opContent = adminOptionContent(joinPoint.getArgs(), jMethod); 
	     
	     //建立日誌物件  
	     Log log = new Log();  
	     log.setMemberId(SubjectUtil.getUser().getId());//設定操作員id  
	     log.setOperation(opContent);//操作  
	     log.setOperationType((short) 1); 
	     log.setIp(InetAddress.getLocalHost().getHostAddress());
	     log.setTime(new Date());
	     
	     logService.insertLog(log);//新增日誌  
	 }  
	 
	 /**
	  * 修改操作日誌(後置通知)
	  * @param joinPoint
	  * @param rtv
	  * @throws Throwable
	  */
	 @AfterReturning(value="updateServiceCall()", argNames="rtv", returning="rtv")  
	 public void updateServiceCallCalls(JoinPoint joinPoint, Object rtv) throws Throwable{  
	     
		 //HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 
	     //判斷引數  
	     if(joinPoint.getArgs() == null){//沒有引數  
	         return;  
	     }  
	     String jMethod = joinPoint.getSignature().getName();
	     String opContent = adminOptionContent(joinPoint.getArgs(), jMethod); 
	     
	     //建立日誌物件  
	     Log log = new Log();  
	     log.setMemberId(SubjectUtil.getUser().getId());//設定操作員id  
	     log.setOperation(opContent);//操作  
	     log.setOperationType((short) 2); //1新增2修改3刪除
	     log.setIp(InetAddress.getLocalHost().getHostAddress());
	     log.setTime(new Date());
	     
	     logService.insertLog(log);//新增日誌  
	 } 
	 
	 /**
	  * 刪除操作日誌(前置通知)
	  * 前置環繞通知在操作物件被刪除前獲取操作物件資訊用於日誌中
	  * @param joinPoint
	  * @param rtv
	  * @throws Throwable
	  */
	 @Before(value="deleteServiceCall()", argNames="rtv")  
	 public void deleteServiceCallCalls(JoinPoint pjp) throws Throwable{  
	     
		 //HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 
	     //判斷引數  
	     if(pjp.getArgs() == null){//沒有引數  
	         return;  
	     }  
	     String jMethod = pjp.getSignature().getName();
	     System.out.println(pjp.getArgs()[0]);
	     String opContent = jMethod+"[引數1,型別:Long,值:"+pjp.getArgs()[0]+"]"; 
	     
	     //建立日誌物件  
	     Log log = new Log();  
	     log.setMemberId(SubjectUtil.getUser().getId());//設定操作員id  
	     log.setOperation(opContent);//操作  
	     log.setOperationType((short) 3); //1新增2修改3刪除
	     log.setIp(InetAddress.getLocalHost().getHostAddress());
	     log.setTime(new Date());
	     
	     logService.insertLog(log);//新增日誌  
	 } 
	 
	 /** 
	   * 使用Java反射來獲取被攔截方法(insert、update)的引數值, 
	   * 將引數值拼接為操作內容 
	   */  
	  public String adminOptionContent(Object[] args, String mName) throws Exception{  
		
	      if (args == null) {  
	          return null;  
	      }  
	        
	      StringBuffer rs = new StringBuffer();  
	      rs.append(mName);  
	      String className = null;  
	      int index = 1;  
	      // 遍歷引數物件  
	      for (Object info : args) {  
	            
	          //獲取物件型別  
	          className = info.getClass().getName();  
	          className = className.substring(className.lastIndexOf(".") + 1);  
	          rs.append("[引數" + index + ",型別:" + className + ",值:");  
	            
	          // 獲取物件的所有方法  
	          Method[] methods = info.getClass().getDeclaredMethods();  
	            
	          // 遍歷方法,判斷get方法  
	          for (Method method : methods) {  
	                
	              String methodName = method.getName();  
	              // 判斷是不是get方法  
	              if (methodName.indexOf("get") == -1) {// 不是get方法  
	                  continue;// 不處理  
	              }  
	                
	              Object rsValue = null;  
	              try {  
	                    
	                  // 呼叫get方法,獲取返回值  
	                  rsValue = method.invoke(info);  
	                    
	                  if (rsValue == null) {//沒有返回值  
	                      continue;  
	                  }  
	                    
	              } catch (Exception e) {  
	                  continue;  
	              }  
	                
	              //將值加入內容中  
	              rs.append("(" + methodName + " : " + rsValue + ")");  
	          }  
	            
	          rs.append("]");  
	            
	          index++;  
	      }  
	        
	      return rs.toString();  
	  }  


	  //獲取客戶端ip
	  public static String getIp(HttpServletRequest request) {
          String ip = request.getHeader("X-Forwarded-For");
          if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
              //多次反向代理後會有多個ip值,第一個ip才是真實ip
              int index = ip.indexOf(",");
              if(index != -1){
                  return ip.substring(0,index);
              }else{
                  return ip;
              }
          }
          ip = request.getHeader("X-Real-IP");
          if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
              return ip;
          }
          return request.getRemoteAddr();
      }
}
applicationContext.xml
<!-- 加入Aspectj配置 -->  
    <aop:aspectj-autoproxy />  
    <bean id="logAspect" class="com.jusfoun.estate.aop.LogAspect" />