2013-09-11 2 views
0

Мой ApplicationContext выглядит следующим образомSpring AOP Controller Исполнительное дважды

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns=".."> 
    <mvc:annotation-driven/> 
    <task:annotation-driven/> 
    <mvc:resources mapping="/resources/**" location="/resources/"/> 
    <aop:aspectj-autoproxy /> 
    <context:component-scan base-package="com.abc"> 
     <context:include-filter type="aspectj" expression="com.abc.aspects.LogControllerAspect"/> 
    </context:component-scan> 
    <context:annotation-config /> 
</beans> 

Есть 2 Аспект Java классы, LogControllerAspect (для регистрации всех вызовов на пружинные Controllers) и LogDAOAspect (для регистрации всех вызовов к БД).

@Aspect 
@Service 
public class LogDAOAspect { 
    private Logger logger = LoggerFactory.getLogger(this.getClass()); 

    @Around("execution(* com.*.*DAOImpl.*(..))") 
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { 
     String methodId = joinPoint.getTarget().getClass().getSimpleName()+" : "+joinPoint.getSignature().getName() + " : " + ((joinPoint.getArgs()==null||joinPoint.getArgs().length<1)?"":(Arrays.toString(joinPoint.getArgs()))); 
     Object returnVal = null; 
     StopWatch sw = new StopWatch(methodId); 
     try { 
      sw.start(); 
      returnVal= joinPoint.proceed(joinPoint.getArgs()); 
      sw.stop(); 
     } catch (Throwable e) { 
      logger.error(methodId+"\n"+e); 
      throw e; 
     } 
     logger.debug(methodId + ":" +sw.getTotalTimeMillis()); 
     return returnVal; 
    } 
} 


@Aspect 
public class LogControllerAspect { 
    private Logger logger = LoggerFactory.getLogger(this.getClass()); 

    @Around("execution(* com.*.*Controller.*(..))") 
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { 
     String methodId = joinPoint.getTarget().getClass().getSimpleName()+" : "+joinPoint.getSignature().getName() + " : " + ((joinPoint.getArgs()==null||joinPoint.getArgs().length<1)?"":(Arrays.toString(joinPoint.getArgs()))); 
     Object returnVal = null; 
     StopWatch sw = new StopWatch(methodId); 
     try { 
      sw.start(); 
      returnVal= joinPoint.proceed(joinPoint.getArgs()); 
      sw.stop(); 
     } catch (Throwable e) { 
      logger.error(methodId+"\n"+e); 
      throw e; 
     } 
     logger.debug(methodId + ":" +sw.getTotalTimeMillis()); 
     return returnVal; 
    } 
} 

LogDAOAspect прекрасно, но LogControllerAspect регистрирует дважды (метод logAround дважды исполнения), когда я прошу некоторые страницы. Я могу понять, что этот аспект дважды проксируется, но я не уверен, как этого избежать. Помогите оценить.

+0

Вы уверены, что методы управления запускаются один раз? возможно, есть два вызова метода. – erencan

+0

Метод вызывается только один раз (я установил точку останова, которую он ударил только один раз) –

+0

вы должны проверить любой метод в пакете COntroller '* com. *. * Контроллер. * (..))' – erencan

ответ

0

Это была глупая ошибка. Это даже не проблема, связанная с весной! У меня была установка log4j следующим образом !!! ??? !!!

<appender name="AppAppender" class="org.apache.log4j.DailyRollingFileAppender"> 
    <param name="DatePattern" value=".yyyy-MM-dd.HH"/> 
    <param name="File" value="logs/logfile.log"/> 
    <param name="Append" value="true"/> 
    <layout class="org.apache.log4j.PatternLayout"> 
     <param name="ConversionPattern" value="%-5p : %d{ISO8601} : %m%n"/> 
    </layout> 
</appender> 

<logger name="com.abc.aspects.LogControllerAspect"> 
    <priority value="debug"></priority> 
    <appender-ref ref="AppAppender"/> 
</logger> 

<root> 
    <priority value="error" /> 
    <appender-ref ref="AppAppender" /> 
</root> 

Спасибо @erencan. Вы действительно помогли мне внимательно посмотреть, что действительно происходит внутри этого метода.

Изменен в следующем, и он отлично работает. Должен log4j к тегам этого вопроса!

<logger name="com.abc.aspects.LogControllerAspect" additivity="false"> 
    <priority value="debug"></priority> 
    <appender-ref ref="AppAppender"/> 
</logger>