2013-12-16 5 views
4

Java 기반 구성을 사용할 때 Spring이 bar()에 대한 두 번째 호출을 방지하는 방법은 무엇입니까?Spring @Configuration 캐시가 bean을 참조하는 방법

나는 시간 주석 처리를 컴파일하거나 메소드를 프록 싱하는 것이 궁금한가요?

@Configuration 
public class AppConfig { 

    @Bean 
    public Foo foo() { 
     return new Foo(bar()); 
    } 

    @Bean 
    public Foo foo2() { 
     return new Foo(bar()); 
    } 

    @Bean 
    public Bar bar() { 
     return new Bar(); 
    } 
} 

답변

4

이 당신의 상황 때문에 @Configuration

AnnotationConfigApplicationContext context = 
    new AnnotationConfigApplicationContext(AppConfig.class); 

같은 작은 선물을 만들어 봄 유형 AppConfig 및 프록시를의 빈을 생성합니다. ConfigurationClassEnhancer (implementation details.)

이러한 메서드는 개체에서 직접 호출되지 않습니다. 분명히 그들은 컴파일 시간에 알려지지 않았기 때문에 그렇게 할 수 없습니다. 그들은 프록시에 반영을 통해 호출됩니다.

그래서 당신이있을 때

@Bean 
public CustomBean foo() { 
    return new CustomBean(bar()); 
} 

@Bean 
public CustomBean foo() { 
    return new CustomBean(this.bar()); 
} 

this 메소드 호출의 결과를 캐시 프록시를 참조한다에 해당하는 그것이 전에이라고하면 즉시 반환 .

+0

아, 좋은 올인원 '신비한 봄 automagic. 왜 단지 인자 주입을 사용하지 않는가? –

+0

@ leo-the-manic'@ Autowired '주석이 달린 메소드를 사용하고 싶습니까? 때로는 선택의 여지가 없습니다. 'CustomBean'은 다른 초기화 메소드를 노출시키지 않는 제 3 자 클래스 일 수 있습니다. –

+0

내 의견이 귀하의 대답보다는 봄 자체에 맞춰 졌다고 생각합니다. 엄격하게 Java 관점에서 코드를 보면 두 개의 다른 인스턴스를 생성하는 것처럼 보입니다. 나는 Spring이 자동으로 더 명백하고 이해하기 쉬운 것을하기보다는 당신을 위해 메소드를 프록시/캐시하기로 결정했다는 것을 싫어한다. –

0

스프링은 bar()에 대한 호출을 "방지"하지 않습니다. 대신 시작시 스프링은 @Bean이라는 메서드 목록을 생성 한 다음 각 메서드를 한 번 호출합니다. 원하는 경우 bar() 번을 100 번 부를 수 있습니다. 그러나, 봄, 그러나; 한 번만 호출합니다. 이 @Bean 방법을 가지고 있기 때문에 당신을 가정

관련 문제