2013-12-16 3 views
4

Как Spring предотвращает второй вызов bar() при использовании конфигураций на основе Java?Как ссылается кеширование Spring @Configuration на beans

Мне интересно компилировать обработку аннотации времени или путем проксирования метода?

@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

Предполагая, что вы создали ваш контекст немного что-то вроде

AnnotationConfigApplicationContext context = 
    new AnnotationConfigApplicationContext(AppConfig.class); 

Из-за @Configuration, Spring создаст боб типа AppConfig и прокси, потому что он имеет @Bean методы. Вы должны проверить ConfigurationClassEnhancer за implementation details.

Эти методы не вызываются непосредственно на объект. Очевидно, они не могут, поскольку они не известны во время компиляции. Они вызываются через отражение на прокси.

Так что, когда у вас есть

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

что эквивалентно

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

this имеет в виду прокси, который кэширует результат вызова метода и возвращает его немедленно, если он называется его перед ,

+0

А, добрый ол 'таинственный Пружинный автомат. Почему бы просто не использовать инъекцию параметров? –

+0

@ leo-the-manic Вы имеете в виду через '@ Autowired' аннотированные методы? Иногда у вас нет выбора. 'CustomBean' может быть сторонним классом, который не предоставляет другого метода инициализации. –

+0

Я полагаю, что мой комментарий больше ориентирован на весну, а не на ваш ответ. Глядя на код с строго точки зрения Java, он выглядит так, как будто он создаст два разных экземпляра. Мне не нравится, что Spring выбрала автоматическое прокси/кеширование методов для вас, а не делать что-то более очевидное и понятное. –

0

Весна не «предотвращает» звонок до bar(). Вместо этого при запуске весна генерирует список меток, отмеченных @Bean, а затем вызывает каждый метод один раз. Если вы хотите, вы можете позвонить по телефону bar() сто раз. Весна, однако; будет называть его только один раз.