2015-06-16 6 views
2

Может ли кто-нибудь объяснить мне, почему @Bean по статическому методу возвращает 2 разных экземпляра?@Bean аннотация по статическому методу

Я могу понять, что @Bean по методу, не статическому, как класс A, возвращает тот же экземпляр, поскольку область по умолчанию является singleton.

И если я попытаюсь ввести класс B с @Autowire в службу, это не сработает, поэтому похоже, что это не загрузка контекста приложения Spring. Так что с использованием класса D будет схоже!? Я думаю, не потому, что для @PropertySource мы должны использовать в дополнение (используется для заполнителем):

@Bean 
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 
    return new PropertySourcesPlaceholderConfigurer(); 
} 

и если удалить @Bean из этого, он не будет работать.

Есть ли другой вариант использования, когда было бы полезно использовать @Bean для статического метода?

Пример:

когда я бегу:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = {Conf.class}) 
public class Test { 
    @org.junit.Test 
    public void test(){ 
    } 
} 

для

@Configuration 
@ComponentScan 
public class Conf { 

    @Bean 
    public A aaa(){ 
     return new A(); 
    } 

    @Bean 
    public static B bbb(){ 
     return new B(); 
    } 

    @Bean 
    @Scope("prototype") 
    public C ccc(){ 
     return new C(); 
    } 

    public static D ddd(){ 
     return new D(); 
    } 

    @PostConstruct 
    public void post(){ 
     System.out.println(aaa()); 
     System.out.println(aaa()); 
     System.out.println(bbb()); 
     System.out.println(bbb()); 
     System.out.println(ccc()); 
     System.out.println(ccc()); 
     System.out.println(ddd()); 
     System.out.println(ddd()); 
    } 

} 
public class A { 
} 
public class B { 
} 
public class C { 
} 
public class D { 
} 

я получаю:

[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 

ответ

6

Поскольку вы создаете новый объект для каждого вызова метода в bbb(). Взаимозависимости между компонентами (если вы просто вызываете метод создания бобов), таким образом, создаете прокси-сервер для вашего класса конфигурации, а прокси-сервер перехватывает вызовы методов методам bean для доставки правильного компонента (singleton, prototype и т. Д.).). Однако статические методы не проксируются, поэтому, когда вы вызываете статический метод, Spring не знает об этом, и вы просто получаете обычный Java-объект. С PropertySourcesPlaceholderConfigurer это отличается, потому что этот метод напрямую не вызван в этом классе, компонент будет вводиться только там, где он используется.

1

@Bean аннотированные методы проксируются, чтобы обеспечить правильный экземпляр bean. Статические методы не проксируются. Следовательно, в вашем случае вызов bbb() каждый раз дает новый экземпляр B.

PropertySourcesPlaceholderConfigurer класс - особый вид компонента, поскольку он реализует BeanFactoryPostProcessor. В жизненном цикле контейнера объект BeanFactoryPostProcessor должен быть создан ранее, чем объект @ Configuration-annotated класса. Также вам не нужно вызывать этот статический метод.

См Бутстрапирование раздел в Java документ: [http://docs.spring.io/spring/docs/4.2.x/javadoc-api/org/springframework/context/annotation/Bean.html][1]

Особое внимание должны быть приняты для @Bean методов, которые возвращают типы Spring BeanFactoryPostProcessor (BFPP). Поскольку объекты BFPP должны быть созданы очень рано в жизненном цикле контейнера, они могут вмешиваться в обработку аннотаций, таких как @Autowired, @Value, и @PostConstruct в классах @Configuration. Чтобы избежать проблем с жизненным циклом , отметьте BFPP-возвращающие методы @Bean как статические

Смежные вопросы