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.");
}
}
}
spring的aop做日誌的控制
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.