我正在使用Spring 4并且我不想为每个DAO方法编写记录器,而是我想编写一个方面或拦截器,它可以拦截每个dao方法并将日志放在方法体和内部catch块中。这样做的正确方法是什么?我怎样才能做到这一点?
我尝试编写Spring-Advice,但我无法将logger放在catch块内或方法内。
我的问题是如何编写代码,以便记录器可以放在每个Dao方法体内,也可以在同一方法的catch块中,如果有任何错误 < / p>
这是我的Dao类方法,我不写任何日志
public Person xyz(SomeObject model) {
Myresponse response=new Myresponse();
try {
DemoClass blocking=new DemoClass(jdtmp);
blocking.setlmfuncparam1(model.getCode());
blocking.setlmfuncparam2(model.getIdentification());
blocking.startaction();
return response;
}catch(BusinessValidationException e)
{
response.setErrorCode(e.getErrorCode());
response.setErrorDescription(e.getErrorMessage());
response.setSuccess(false);
}
catch (Exception e) {
throw new InternalServiceException(APIConstants.INTERNAL_SERVER_ERROR_CODE,
APIConstants.INTERNAL_SERVER_ERROR_REQUEST_UNABLE_TO_PROCESS);
}
return response;
}
我想编写AOP或Interceptor,通过这种方法,上面写的每个方法都会有像下面这样的Logger
<code>
public Person xyz(SomeObject model) {
**FILE_LOGGER.debug("In MyDaoImpl Class - xyz method");**
Myresponse response=new Myresponse();
try {
DemoClass blocking=new DemoClass(jdtmp);
blocking.setlmfuncparam1(model.getCode());
blocking.setlmfuncparam2(model.getIdentification());
blocking.startaction();
return response;
}catch(BusinessValidationException e)
{
response.setErrorCode(e.getErrorCode());
response.setErrorDescription(e.getErrorMessage());
response.setSuccess(false);
}
catch (Exception e) {
**FILE_LOGGER.error(Util.getStackTraceAsString(e));**
throw new InternalServiceException(APIConstants.INTERNAL_SERVER_ERROR_CODE,
APIConstants.INTERNAL_SERVER_ERROR_REQUEST_UNABLE_TO_PROCESS);
}
return response;
}
答案 0 :(得分:0)
我没有看到任何问题,我建议捕捉的小改变如下:
@Aspect
@Slf4j
@Component
public class LoggerAspect {
@Around("execution(* com.foo.bar.api.ws.dao..*.*(..))")
public Object printServiceLogger(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
StopWatch stopWatch = new StopWatch();
stopWatch.start(proceedingJoinPoint.toShortString());
String throwableName = null;
try {
// execute the profiled method
return proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
throwableName = throwable.getClass().getName();
throw throwable;
} finally {
stopWatch.stop();
if (throwableName != null) {
log.error("ERROR while processing request " + proceedingJoinPoint.getSignature().toString() + " " + +stopWatch.getTotalTimeMillis()
+ " milliseconds with exception [" + throwableName + "]");
} else {
log.debug("Total taken for processing request " + proceedingJoinPoint.getSignature().toString() + " " + +stopWatch.getTotalTimeMillis()
+ " milliseconds");
}
}
}
}
你也可以使用 Afterthrowing
答案 1 :(得分:0)
示例代码中的第一个logger语句可以替换为Spring AOP中的简单@Before("execution(* *(..))")
建议。当然,你应该将切入点从拦截所有方法缩小到只有你感兴趣的方法,类似于 Yogi 的例子。但是,由于您既没有解释DAO类的共同点(包名,类名模式,实现的接口或基类),也没有在代码中显示任何包或类名,所以现在我不能给你一个更具体的例子。 (如果你在SO上提出不清楚的问题,你只能得到一些不明确的答案,对不起。)
问题是catch
块内的第二个日志语句。在AspectJ中,你可以使用handler()
切入点,但是Spring AOP does not support it。所以如果你真的想要这个,你需要在Spring中activate full AspectJ via LTW (load-time weaving)。
解决方法不是拦截catch块本身,而是通过InternalServiceException
建议拦截抛出的@AfterThrowing
。这个解决方案的缺点是你的非正统的异常处理方式:你实例化新的异常,但不要在构造函数中给它原始的异常作为原因。您只是吞下原始异常,使调试变得不必要。这是异常处理的一种不好的方式。因此,根据@AfterThrowing
建议,在这种情况下,您无法再记录原始异常。
底线:重构或切换到AspectJ。
P.S。:随意为您的问题添加更多细节,然后我可以提供具体的方面代码示例。