2014-01-18 4 views
4

것은 나에게 처음 foremention하자, 내가 직면하고있어 문제는 내가 작업에 봄에서 자습서를 실행 해요이 Spring Aspect가 메소드 매개 변수와 같이 인쇄되지 않는 이유는 무엇입니까?

를 인쇄하지 첫 번째 코드 블록에서의
interceptThoughts(String thoughts)
방법입니다
. 가로 세로가 Volunteerimplements Thinker 해당 인터페이스의 마음을 읽을 생각하는 Magician 클래스 그 implements MindReader 방법 interceptThoughts(String thoughts)와 인터페이스와 getThoughts()

@Aspect 
public class Magician implements MindReader { 

    private String thoughts; 

    @Pointcut("execution(* com.underdogdevs.myspringaspectj." 
      + "Thinker.thinkOfSomething(String)) && args(thoughts)") 
    public void thinking(String thoughts) { 
    } 

    @Override 
    @Before("thinking(thoughts)") 
    public void interceptThoughts(String thoughts) { 
     System.out.println("Intercepting volunteer's thoughts : " + thoughts); 
     this.thoughts = thoughts; 
    } 

    @Override 
    public String getThoughts() { 
     return thoughts; 
    } 
} 

는 방법 나는 내 자바 BeanConfigthinkOfSomething(String thoughts)

public class Volunteer implements Thinker { 

    private String thoughts; 

    @Override 
    public void thinkOfSomething(String thoughts) { 
     this.thoughts = thoughts; 
     System.out.println("Something"); 
    } 

    public String getThoughts() { 
     return thoughts; 
    } 
} 

함께있다 MagicianVolunteer

@Configuration 
public class BeanConfig { 

    @Bean 
    public MindReader magician() { 
     return new Magician(); 
    } 

    @Bean 
    public Thinker volunteer() { 
     return new Volunteer(); 
    } 
} 

그리고

public class App { 
    public static void main(String[] args) { 
     ApplicationContext context = 
       new ClassPathXmlApplicationContext("spring-idol.xml"); 

     System.out.println(); 
     Thinker volunteer = (Thinker)context.getBean("volunteer"); 
     volunteer.thinkOfSomething("This is what I'm thinking"); 
    } 
} 

  • NO Eorrrs
  • 예외
  • 패키지 interceptThoughts 방법에 선을 인쇄하지하는 Magician 방법을 얻기 위해 그것을 실행하기 위해 노력하고있어 Magician 부분의 @Pointcut(execution(에서 올바른 것입니다.
  • 나는 문제는 예상대로 인쇄되지 않는 Magician 측면에서 @Before 나의 봄 구성 XML

    <context:component-scan base-package="com.underdogdevs.myspringaspectj" /> 
    <aop:aspectj-autoproxy /> 
    

이 두 항목이있다. 여기에 뭔가가 빠졌습니까? 인쇄되지 않는 이유는 무엇입니까? 나는 인수를 취하지 않고 잘 실행하는 다른 aspect 메소드를 가지고있다. 매개 변수 값을 올바르게 전달하지 않습니까?

+0

이 야생 추측 할 수있다; Volunteer와 Magician에게'@ Component's로 주석을 달았습니까? 또는 @Before 주석 안에 pointcut을 두는 것입니까? –

+0

! guido 방금 시도했지만 작동하지 않습니다. 은 컨텍스트 내에서 bean을 스캔하기 위해서'@ Component'를 정확하게 지정하지 않고있는 것입니다. –

+0

실제로'context : component-scan'은 * @Component 주석 (@Service, @Controller, 또한 @Component로 메타 주석이 첨부 된 @Configuration)을 검색 할 때 클래스 *를 검색하십시오. –

답변

1

는이

@Configuration 
public class BeanConfig { 

    @Bean 
    public Magician magician() { 
     return new Magician(); 
    } 
... 

나는 그것이 봄의 문서에 있는지 여부를 모르는 노력하지만, 그것은 봄 analizes이 magician()의 형식을 반환하는 경우 것이 분명하고있을 때 MindReader 봄은 주석에 볼 수 없습니다 그것.

+0

왜 이것이 작동하는지 설명해주십시오.모든 aspect bean은 구체적인 클래스로 이런 식으로 선언 될 필요가 있는가? –

+0

확인, 내 업데이트를 참조하십시오 –

2

Evgeniy에는 해결책이 있습니다. 단지 어떻게되는지 설명하고 싶습니다.

당신이

<aop:aspectj-autoproxy /> 

을 지정하거나 @EnableAspectJAutoProxy와 (당신이로드)를 @Configuration 클래스를 주석, 봄은 현재의 BeanPostProcessor

프로세스의 모든 AspectJ의 주석 부분을하는 AnnotationAwareAspectJAutoProxyCreator 등록 응용 프로그램 컨텍스트 및 스프링 어드바이저. 모든 AspectJ를 주석 클래스 가 자동으로 인식되며, 봄 AOP의 프록시 기반 모델을 적용 할 경우 자신의 조언을 적용했다. 이 과정의

한 걸음 후보 자문을 찾는 포함됩니다. Bean 정의를 검색하고 Bean 유형을 검사하면됩니다. 이것은 빈이 생성되기 전에 발생하기 때문에 프로세스는 선언 된 것에 의존 할 수 있습니다. 그것은 추측입니다.

<bean> 선언을 사용하면 특별히 class 특성에서 빈의 클래스를 선언하므로 일반적으로 문제가되지 않습니다.

@Bean와 방법 그러나, 대신 인터페이스를 지정할 수 있습니다. 당신이 빈을 생성하는 팩토리 메소드를 사용하고있는 경우 <bean>@Bean 선언이 실패 할 수 모두 있습니다.

는 그래서 AnnotationAwareAspectJAutoProxyCreator 컨텍스트에있는 모든 bean 정의를 살펴보고 자신의 유형을 추측. @Bean 선언을 사용하면 메소드의 리턴 유형을 조사합니다.

귀하의 경우, 반환 유형은 @Aspect 주석이 없으므로 후보가 아닌 MindReader이됩니다. 따라서 조언 (프록시 없음)이 적용되지 않으며 예상 한 동작을 볼 수 없습니다.

가능한 해결책 :

  • Evgeniy's solution는 반환 형식을 변경하고 따라서 명백한 빈 유형이
  • @Bean 정의를 제거하십시오 무엇 봄을 만들 수는 @ComponentMagician 클래스에 주석하고있다 패키지는 component-scan입니다. 그 타입은 분명히 주석이 달린 클래스이기 때문에 Spring은 @Aspect이라는 주석이 붙어 있다는 것을 알 수 있습니다. 콩의 종류를 추측 다른 많은 BeanPostProcessor 구현입니다

참고. 초기화 (또는 초기화 전) 처리가 일어나는 시점을 알아야합니다. 당신의 측면이 나에게 올바른 것 때문에

+0

그 중 하나에 대해 감사합니다;) –