2015-01-07 6 views
1

저는 Spring AOP를 사용하여 Aspect를 만듭니다. 내가 정의한 Aspect는 두 번 실행됩니다. 나는 이유를 알 수없는 것 같습니다. 나는 누군가가이 문제에 관해 어떤 의견을 가지고 있어도 감사 할 것이다.봄 AOP 조언이 두 번 실행 중입니다

감사합니다.

// 봄 구성

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" 
    default-autowire="no" 
    default-lazy-init="true"> 

    <bean id="loggingAdvice" class="com.xyz.aop.LoggingAdvice" /> 
    <aop:config> 
     <aop:aspect id="loggingAspect" ref="loggingAdvice"> 
      <aop:pointcut id="loggingPointcut" 
       expression="execution(* com.xyz.FooServiceImpl.foo(..))"/> 
       <aop:around pointcut-ref="loggingPointcut" method="log" /> 
     </aop:aspect> 
    </aop:config> 

    <context:component-scan base-package="com.xyz.controllers" /> 

</beans> 

// 조언

package com.xyz.aop; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.aspectj.lang.ProceedingJoinPoint; 

public class LoggingAdvice { 
    public Object log(final ProceedingJoinPoint pjp) throws Throwable { 
     log.info("Started!"); 
     try { 
      return pjp.proceed(); 
     } finally { 
      log.info("Ended!"); 
     } 
    } 
} 

// 방법

package com.xyz; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 

public class FooServiceImpl implements FooService { 
    private static final Log log = LogFactory.getLog(FooServiceImpl.class); 

    @Override 
    public void foo() { 
     log.info("Foo!"); 
     } 
    } 
} 

// 출력

Started! 
    Started! 
    Foo! 
    Ended! 
    Ended! 
자문

// 편집 1 : 추가 스프링 구성 정보를 추가했습니다. Spring AOP 어노테이션을 전혀 사용하지 않는다. 디버거를 부착하고 aspect/log 문이 두 번 실행되는 것을 보았습니다. 그래서 그것은 문자열 문을 두 번 인쇄하는 것과 아무런 관계가 없다는 것을 의심합니다.

+6

두 번 실행하면 두 번 감지되고 적용됩니다. '@Aspect' 또는 AOP를 적용하는 다른 방법도 없도록하십시오. –

+0

@ M.Deinum : 답변에 대한 의견을 이동할 수 있습니다. 나는 그것이 정확하다고 생각한다. – kriegaex

+0

더 많은 구성을 게시 할 수 있습니까? 그것은 당신의 전체'LoggingAdvice'입니까, 아니면 누락 된 주석이 있습니까, 동일한 것이 제가 더 의심스러운 구성에 적용됩니다 ... –

답변

-1

왜냐하면 <aop:around ...>은 메소드 앞뒤에서 작업을 수행하기 때문입니다. 한 번만 실행하는 대신 <aop:before...> 또는 <aop:after...>을 사용할 수 있습니다.

+3

이것은 실제로 이해가되지 않습니다. – kriegaex

0

글쎄, 실제로 로거에 문제가있는 것처럼 보입니다. 동일한 문제가 발생하여 오랜 시간 동안 문제가 발생하여 모든 것이 두 번 기록됩니다. 정기적 인 sysout 호출로 로거 호출을 바꿀 때 모든 것이 잘 동작했습니다.

+0

이것은별로 의미가없는 것처럼 보입니다. – kriegaex

+1

이것은 로거와 아무 관련이 없습니다. 로그 문을 Sys.out 문으로 대체하고 두 번 실행 한 사실을 발견했습니다. 실제로 디버거를 연결하고이를 확인하기 위해 프로그램을 밟았습니다. – user544192