spring的aop做日誌的控制

1.先用Aspect取得切入點,然後出入切入點了。
2,在要切入的地方加入自定義的註釋。然後獲取自定義註釋的值寫入日誌文件即可.

如下列:
@Configurable
@Aspect
public class LoggingAspect {
    private static Log logger = LogFactory.getLog(LoggingAspect.class);
   
    @Autowired
    private SystemThreadLocalMap threadLocalMap;

    @Autowired
    private ArgsLogger argsLogger;

    @Pointcut("execution (* com.sinosoft.core.log.aspect.TestService.*(..))")
    public void servicePointCut() {
    }

    @Around("servicePointCut()")
    public void serviceAdvice(ProceedingJoinPoint pjp) throws Throwable {
        String operationMethodName = pjp.getSignature().getName();
        argsLogger.debug(pjp.getArgs(),operationMethodName);
       
        recordServiceMetaInfo(pjp);
        try {
            pjp.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
            if (logger.isErrorEnabled()) {
                logger.error("Exception Caught!"); //$NON-NLS-1$
                //異常的時候打印參數,以方便調試
                argsLogger.error(pjp.getArgs(), operationMethodName);
            }
            //拋出原日誌,讓上層(展現層)處理
            throw e;
        }

        if (logger.isInfoEnabled()) {
            logger.info(getOperationLog()); //$NON-NLS-1$
        }
       
    }

private String getOperationLog() {
        String serviceDesc = (String) threadLocalMap.get(SystemThreadLocalMap.SERVICE_DESCRIPTION);
        String operationDesc = (String) threadLocalMap.get(SystemThreadLocalMap.OPERATION_DESCRIPTION);
        String userID = (String) threadLocalMap.get(SystemThreadLocalMap.USER_ID);
        String userName = (String) threadLocalMap.get(SystemThreadLocalMap.USER_NAME);
        return
                SystemThreadLocalMap.USER_ID+"=" + userID +
                ","+SystemThreadLocalMap.USER_NAME+"=" + userName +
                ","+SystemThreadLocalMap.SERVICE_DESCRIPTION+"=" + serviceDesc +
                ","+SystemThreadLocalMap.OPERATION_DESCRIPTION+"=" + operationDesc;

    }

    private void recordServiceMetaInfo(ProceedingJoinPoint pjp) {
        try {
            String serviceDesc = this.getClassAnnotation(pjp);
            String operationDesc = this.getMethodAnnotation(pjp);
            threadLocalMap.put(SystemThreadLocalMap.SERVICE_DESCRIPTION, serviceDesc);
            threadLocalMap.put(SystemThreadLocalMap.OPERATION_DESCRIPTION, operationDesc);
           
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
   
    /**
     * To get the defined method's annotation of the target class
     * @param pjp
     * @return
     * @throws ClassNotFoundException
     */
    private String getMethodAnnotation(ProceedingJoinPoint pjp) throws ClassNotFoundException{
        String pjpStr = "";
        String localStr = "";
        String rtStr = "";
        Method[] m = this.getTargetMethods(pjp);

        // To get the method name and arguments information of the target method
        pjpStr += pjp.getSignature().getName();
        int argLen = pjp.getArgs().length;
        for (int i = 0; i < argLen; i++) {
            pjpStr += pjp.getArgs()[i].getClass().getName();
        }

        // check to get the annotation
        for (int i = 0; i < m.length; i++) {
            if (pjp.getArgs().length == m[i].getGenericParameterTypes().length) {
                if (pjp.getSignature().getName().equals(m[i].getName())) {
                    if (pjp.getArgs().length > 0) {
                        localStr = "";
                        localStr += m[i].getName();
                        for (int j = 0; j < m[i].getGenericParameterTypes().length; j++) {
                            localStr += m[i].getGenericParameterTypes()[j].toString().substring(6);
                        }
                        if (pjpStr.equals(localStr)) {
                            Annotation annotation1 = m[i]
                                    .getAnnotation(OperationDescription.class);
                            OperationDescription des = (OperationDescription) annotation1;
                            rtStr = des.funtion();
                            localStr = "";
                        }
                    } else {
                        Annotation annotation1 = m[i]
                                .getAnnotation(OperationDescription.class);
                        OperationDescription des = (OperationDescription) annotation1;
                        rtStr = des.funtion();
                    }
                }
            }
        }

        return rtStr;
    }
   
    /**
     * To get the annotation of the target class
     * @param pjp
     * @return
     * @throws ClassNotFoundException
     */
    private String getClassAnnotation(ProceedingJoinPoint pjp) throws ClassNotFoundException{
        Class cls = this.getTargetClass(pjp);
        Annotation annotation = cls.getAnnotation(ServiceDescription.class);
        ServiceDescription d = (ServiceDescription) annotation;
        return d.value();
    }
   
    /**
     * To get the target class
     * @param pjp
     * @return
     * @throws ClassNotFoundException
     */
    private Class getTargetClass(ProceedingJoinPoint pjp) throws ClassNotFoundException{
        String classname = pjp.getTarget().getClass().toString().substring(6);
        Class cls = Class.forName(classname);
        return cls;
    }
   
    /**
     * To get the methods of the target class
     * @param pjp
     * @return
     * @throws ClassNotFoundException
     */
    private Method[] getTargetMethods(ProceedingJoinPoint pjp) throws ClassNotFoundException{
        Class cls = this.getTargetClass(pjp);
        Method[] methods = cls.getMethods();
        return methods;
    }
該類定義了切入點和對切面的處理,在其中你看到了OperationDescription個註釋和ServiceDescription註釋:這兩個是自定義的註釋:
@Target(ElementType.METHOD)  
@Retention(RetentionPolicy.RUNTIME)

public @interface OperationDescription {
    String funtion();
}

@Target(ElementType.TYPE)  
@Retention(RetentionPolicy.RUNTIME)

public @interface ServiceDescription {
    String value();
}



下面這個ArgsLogger 類是記錄日誌的輸出
public class ArgsLogger {
    /**
     * Logger for this class
     */
    private static final Log logger = LogFactory.getLog(ArgsLogger.class);

   
    public void debug(Object[] args, String operationMethodName) {
       
        if (logger.isDebugEnabled()) {
            logger.debug(getArgsInfo(args, operationMethodName));
        }
    }
   
    public void error(Object[] args, String operationMethodName) {
        if (logger.isErrorEnabled()) {
            logger.error(getArgsInfo(args, operationMethodName));
        }
       
    }

    private StringBuffer getArgsInfo(Object[] args, String operationMethodName) {
        StringBuffer argsBuffer = new StringBuffer();
        argsBuffer.append("/nprinting the Args of " +operationMethodName+
                "(..):/n");
        for (int i = 0; i < args.length; i++) {
            Object arg = args[i];
            argsBuffer.append("args["+i+"]='").append(arg).append("'/n");
        }
        return argsBuffer;
    }

}

測試類:
@ServiceDescription(value="日誌管理測試")
public class TestService  {
    private static Log log = LogFactory.getLog(TestService.class);

    @OperationDescription(funtion="測試方法")
    public void testu(){
        // do something here
        if (log.isDebugEnabled()){
            log.debug("this is a test method.");
        }
    }
}

轉自:http://blog.chinaunix.net/u/20045/showart_1386311.html

發佈了49 篇原創文章 · 獲贊 4 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章