模板有其局限性。但是,您的问题可以通过 Aspect 非常优雅地解决。( http://www.eclipse.org/aspectj/ ) 只需为您需要的每种“模板案例”创建一个新注释并使用环绕建议。
Ps:不要使用 printStackTrace() 来 syserr/sysout。有这么多生产级的轻量级日志框架.... pleeeaseee... 不要滥用可怜的小 System.out/err :)
编辑:
日志记录/基准测试建议的一些示例。(注意:我使用 spring AOP 进行切面,使用 lombok 轻松访问日志框架。这里的getCurrentUser()
代码并不真正相关,只是为了从 Spring Security 获取当前用户)
package com.XXXXXXXX.aspects;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
@Component
@Aspect
@Slf4j
public class LoggerAspect {
private final static String DOMAIN = "XXXXXXXX";
private static String getCurrentUser() {
String username = "Unknown";
try {
Object principal = SecurityContextHolder.getContext().
getAuthentication().
getPrincipal();
if (principal instanceof UserDetails) {
username = ((UserDetails) principal).getUsername();
} else {
username = principal.toString();
}
} catch (Exception e) {
}
return username;
}
@Pointcut("within(com.XXXXXXXX.services..*)")
public void inServiceLayer() {
}
@Pointcut("execution(* getMatcherInfo(..)) || execution(* resetCounter(..))")
public void notToAdvise() {
}
@Around("com.XXXXXXXX.aspects.LoggerAspect.inServiceLayer() && !com.XXXXXXXX.aspects.LoggerAspect.notToAdvise()")
public Object doLogging(ProceedingJoinPoint pjp)
throws Throwable {
long start = System.nanoTime();
StringBuilder sb = new StringBuilder(DOMAIN);
sb.append('/').
append(getCurrentUser()).
append(" accessing ").
append(pjp.getSignature().
getDeclaringTypeName()).
append('.').
append(pjp.getSignature().
getName());
log.trace("START: " + sb.toString());
Object retVal = pjp.proceed(pjp.getArgs());
long duration = System.nanoTime() - start;
log.trace("STOP: " + duration / 1000000 + " msec. " + sb.toString());
return retVal;
}
}