Hi,
I have got problems ordering some aspect with Spring 2.0.5 (probably me not using correctly Spring but I can't figure out where is the problem).
What is my goal ?
My goal is to intercepts all methods call of my service layer to do 2 things in that order :
1 - report to the supervision system a service call
2 - log the service call (method name, parameters, return value and exception).
This implies to execute first the supervision service interception.
How I have done things ?
I have developped the 2 aspects (a SupervisionInterceptor and a LoggerInterceptor) and they work correctly except that LoggerInterceptor is called before SupervisionInterceptor !
My problem is that I'm not able to tell Spring to execute SupervisionInterceptor before LoggerInterceptor
I have implemented Ordered interface for my advice class but it does seem to change anything.
Here's my config :
Here's my advice beans implementation :Code:<bean id="loggerInterceptor" class="fr.anpe.sapiens.transverse.utils.LoggerInterceptor"> <property name="logExecutionTime" value="true" /> <property name="logExceptionStackTrace" value="false" /> </bean> <bean id="serviceSupervisionInterceptor" class="fr.anpe.sapiens.transverse.utils.ServiceSupervisorInterceptor"/> <aop:config> <aop:pointcut id="serviceOperation" expression="execution(* fr.anpe.sapiens.bas.service.*.*(..))" /> <aop:aspect ref="serviceSupervisionInterceptor"> <aop:before pointcut-ref="serviceOperation" method="superviseService" /> </aop:aspect> <aop:aspect ref="loggerInterceptor"> <aop:around pointcut-ref="serviceOperation" method="logMethodCall" /> </aop:aspect> </aop:config>
I have switched the getOrdered return value in case of ... but no change !Code:public class ServiceSupervisorInterceptor { private static Logger logger = Logger.getLogger(ServiceSupervisorInterceptor.class); public void superviseService(JoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); String serviceName = signature.getMethod().getName(); // on récupère le logger de la classe appelée pour faire une trace Log4j pertinente Object[] arguments = joinPoint.getArgs(); if (ArrayUtils.isEmpty(arguments)) { logger.error("Le service <" + serviceName + "> ne respecte pas les préconisations d'architectures : un service doit avoir un unique paramètre héritant de la classe AbstractDemande !"); return; } try { AbstractDemande demande = (AbstractDemande) arguments[0]; logger.info("Appel du service <" + serviceName + "> par [" + demande.getInfoConsumer() + "]"); } catch (Exception e) { logger.error("Le service <" + serviceName + "> ne respecte pas les préconisations d'architectures : un service doit avoir un unique paramètre héritant de la classe AbstractDemande !"); return; } } public int getOrder() { return 1; } } public class LoggerInterceptor implements Ordered { private static final String EMPTY_STRING = ""; private static final String PARAMETER_SEPARATOR = ", "; private boolean logExecutionTime = false; private boolean logExceptionStackTrace = true; /** * Print information on logger about the method execution. */ public Object logMethodCall(ProceedingJoinPoint joinPoint) throws Throwable { long time = System.currentTimeMillis(); MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Class declaringType = signature.getDeclaringType(); Logger logger = Logger.getLogger(declaringType);; String methodName = signature.getMethod().getName(); try { StringBuffer methodNameLog = new StringBuffer(200); if (logger.isInfoEnabled()) { System.out.println(EMPTY_STRING); } methodNameLog.append("Appel de la méthode ").append(methodName).append("("); Object[] arguments = joinPoint.getArgs(); if (arguments != null && arguments.length > 0) { for (int i = 0; i < arguments.length; i++) { methodNameLog.append(objectToString(arguments[i])); boolean notLastParameter = i < arguments.length - 1; if (notLastParameter) { methodNameLog.append(PARAMETER_SEPARATOR); } } } methodNameLog.append(")"); logger.info(methodNameLog); Object o = joinPoint.proceed(); if (signature.getReturnType().equals(Void.TYPE) == false) { logger.info("> " + methodName + "() a retourné --> " + objectToString(o)); } return o; } catch (Throwable t) { logger.error("> " + methodName + "() a levé l'exception " + StringUtils.getClassNameWithoutPackage(t.getClass()) + " avec comme message : " + t.getMessage()); if (logExceptionStackTrace) { logger.error("stack trace exception : ", t); } throw t; } finally { if (logExecutionTime) { double executionTime = (System.currentTimeMillis() - time); logger.info("> " + methodName + "() executée en " + executionTime + " ms."); } } } /** * return a string description of o. * <p> * better than toString because it manages array ! * * @param o * object to describe * @return string description of o */ private String objectToString(Object o) { if (null == o) { return null; } if (o.getClass().isArray()) { return ArrayUtils.toString(o); } return o.toString(); } public void setLogExecutionTime(boolean logExecutionTime) { this.logExecutionTime = logExecutionTime; } public void setLogExceptionStackTrace(boolean logExceptionStackTrace) { this.logExceptionStackTrace = logExceptionStackTrace; } public int getOrder() { return 0; } }
Here's an extract of somme logging trace :
INFO [bas.service.ObjTrouveService] - Appel de la méthode findObjTrouves(CritereRechercheObjTrouveDemande)
INFO [transverse.utils.ServiceSupervisorInterceptor] - Appel du service <findObjTrouves> par [testFindObjetParClee consumer]
INFO [bas.service.ObjTrouveService] - > findObjTrouves() a retourné --> fr.anpe.sapiens.transverse.paquets.ObjTrouveRepons e@108f8e0
INFO [bas.service.ObjTrouveService] - > findObjTrouves() executée en 1391.0 ms.
Do you have any clue or suggestion to solve this problem ?
Regards,
Joel



Reply With Quote
