基於Spring aop 和JAVA註解方式添加日誌

來源:互聯網
上載者:User

前幾天做項目時,在做系統日誌這一塊,都是在每個方法裏手寫代碼來添加,覺得很繁瑣,考慮到spring有aop的功能,便尋思著用AOP來做這個日誌功能。

首先需要傳入日誌記錄的具體操作名稱,我們可以用java的註解功能來帶入參數,代碼如下:

/** 
* 類的方法描述註解
* @author LuoYu
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Log {

/** 要執行的操作類型比如:add操作 **/
public String operationType() default "";

/** 要執行的具體操作比如:【添加倉庫】 **/
public String operationName() default "";

}

 

註解類編寫好之後,就要考慮spring我切面的問題目了,首先我們要建立一個切點,也就是需要插入的代碼塊,代碼如下:

 

/** * 通過Spring AOP來添加系統日誌 * @author LuoYu */ public class LogAspect extends BaseAction{  private static final long serialVersionUID = -5063868902693772455L;  private Log logger = LogFactory.getLog(LogAspect.class);  @SuppressWarnings( { "rawtypes", "unchecked" } )  public void doSystemLog(JoinPoint point) throws Throwable {            Object[] param = point.getArgs();          Method method = null;          String methodName = point.getSignature().getName();    if (!(methodName.startsWith("set") || methodName.startsWith("get")||methodName.startsWith("query"))){              Class targetClass = point.getTarget().getClass();                method = targetClass.getMethod(methodName, param[0].getClass());  if (method != null) {  boolean hasAnnotation = method.isAnnotationPresent(com.tlj.pcxt.common.logaop.Log.class);    if (hasAnnotation) {                      com.tlj.pcxt.common.logaop.Log annotation = method.getAnnotation(com.tlj.pcxt.common.logaop.Log.class);                        String methodDescp = annotation.operationType()+annotation.operationName();  if (logger.isDebugEnabled()) {                            logger.debug("Action method:" + method.getName() + " Description:" + methodDescp);                        }                        User appUser=(User) this.getHttpServletRequest().getSession().getAttribute("user");  if(appUser!=null){    try{                                com.tlj.pcxt.entity.admin.Log logInfo=new com.tlj.pcxt.entity.admin.Log();                                logInfo.setIp(this.getHttpServletRequest().getRemoteAddr());                              logInfo.setSubmitUser(appUser);                              logInfo.setContent(annotation.operationType()+","+appUser.getUserName()+  "執行【"+annotation.operationName()+"】操作,影響資料的ID集合為["+getID(param[0])+"]");  this.logService.save(logInfo);                            }catch(Exception ex){                                logger.error(ex.getMessage());                            }                        }                    }                }            }        }  
/**      * 通過java反射來從傳入的參數object裡取出我們需要記錄的id,name等屬性,      * 此處我取出的是id      *@author 羅宇      *@date 2013-4-11      *@param obj      *@return      *@return String      */ public String getID(Object obj){  if(obj instanceof String){  return obj.toString();          }          PropertyDescriptor pd = null;          Method method = null;          String v = "";  try{              pd = new PropertyDescriptor("id", obj.getClass());              method = pd.getReadMethod();                v = String.valueOf(method.invoke(obj));           }catch (Exception e) {              e.printStackTrace();          }  return v;      }  }  

切入代碼編寫好之後,需要在applicatioContext.xml裡配置切入規則,也就是說要在哪些方法執行的時候來切入上面編寫的代碼:配置如 下:

 

<aop:aspectj-autoproxy/> <bean id="logAspect" class="com.tlj.pcxt.common.logaop.LogAspect"/> <aop:config> <aop:aspect ref="logAspect"> <aop:pointcut id="logPointCut" expression="                     (execution(* com.tlj.pcxt.service.*.*Impl.add*(..)))                  or (execution(* com.tlj.pcxt.service.*.*Impl.update*(..)))                  or (execution(* com.tlj.pcxt.service.*.*Impl.delete*(..)))              "/> <aop:after pointcut-ref="logPointCut" method="doSystemLog"/> </aop:aspect> </aop:config>

在此我配置的時在方法執行之後插入代碼塊

Xml代碼

  1. <aop:after pointcut-ref="logPointCut" method="doSystemLog"/>

並且是在所有以add,update,delete開頭的方法才執行,其餘的方法將不再匹配。

調用方法如下,

 

@Log(operationType="add操作:",operationName="添加倉庫房間")  public void addWareHouseRoom(WareHouseRoom wareHouseRoom) throws ServiceException {  try{  this.getWareHouseRoomDao().save(wareHouseRoom);      }catch (Exception e) {  throw new ServiceException(e);      }  }  

是在方法頭前添加上面自訂的@Log註解,傳入相關日誌資訊

另外,在LogAspect的doSystemLog方法裡的

 

  1. Object[] param = point.getArgs(); 

就是取出所匹配方法傳入的參數,我們記錄日誌所需要的相關參數就是從這個對象裡取出來的,並且在該方法下面的代碼會檢查所匹配的方法是否有註解@log,如果沒有,會直接跳出該方法,不做任何處理.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.