Регистрация bean-компонентов из класса, аннотированного конфигурацией

У меня есть класс с аннотацией @Configuration (назовем его StubConfiguration), в котором есть единственный метод с аннотацией @Bean. Этот метод возвращает реализацию BeanFactoryPostProcessor, которая отвечает за регистрацию некоторых bean-компонентов. Однако Spring не может разрешить bean-компоненты, которые эта фабрика регистрирует во время выполнения.

Я предполагаю, что StubConfiguration подхватывается сканированием компонентов Spring, BeanFactoryPostProcessor регистрируется, а затем вызывается его метод postProcessBeanFactory(), после чего регистрируются нужные мне bean-компоненты.

Я неправильно думаю об этом? Как я могу зарегистрировать нужные мне bean-компоненты с моим ApplicationContext, используя эту постобработку?


person Tyler Treat    schedule 19.06.2012    source источник
comment
Я думаю, что зависимости bean-компонентов, вероятно, определяются до вызова BeanFactoryPostProcessor. Зачем регистрировать новые bean-компоненты с помощью постпроцессора, а не создавать их непосредственно из класса @Configuration?   -  person matts    schedule 20.06.2012
comment
@matts: постпроцессор сканирует и регистрирует классы с аннотацией @Stub. Я не могу придумать простой способ сделать это иначе.   -  person Tyler Treat    schedule 20.06.2012
comment
Делает ли он что-то особенное с этими заглушками или просто говорит Spring добавить их в контекст приложения и обработать как обычно?   -  person matts    schedule 20.06.2012
comment
Он просто находит их и регистрирует как одноэлементные компоненты.   -  person Tyler Treat    schedule 20.06.2012


Ответы (2)


Если вы также используете контекст XML-приложения для объявления bean-компонентов, вы можете указать Spring выполнить сканирование компонентов и обработать @Stub как аннотацию компонента Spring.

<context:component-scan base-package="your.base.package">
    <context:include-filter type="annotation" expression="your.stub.package.Stub"/>
</context:component-scan>

Если вы используете только контекст приложения конфигурации аннотаций, ознакомьтесь с этот ответ для способ сделать это без XML.

person matts    schedule 19.06.2012
comment
Я не уверен, что полностью следую. У меня есть классы-заглушки, которые аннотированы аннотацией Stub, которая также содержит имя компонента, например. @Stub("myStub"). Затем позже, например, я мог бы захотеть сделать что-то вроде context.getBean("myStub", MyStub.class). - person Tyler Treat; 20.06.2012
comment
Есть ли в вашем проекте файл applicationContext.xml (или другой файл контекста XML Spring), которым вы управляете? Тег component-scan идет туда и говорит Spring искать в указанном пакете и находить классы с указанной аннотацией. Эти классы добавляются как bean-компоненты в контекст приложения. (Однако они будут названы с использованием стратегии именования по умолчанию, которая просто использует имя класса.) Если у вас нет файла контекста приложения Spring, это нужно сделать другим способом. - person matts; 20.06.2012
comment
Это работает, хотя оказалось, что мне просто нужно было добавить пакет, в котором находилась фабрика, в base-package из component-scan. Поскольку он был в отдельном пакете, Spring не подхватывал его. Добавление этого приводит к регистрации bean-компонентов во время постобработки. - person Tyler Treat; 21.06.2012

Как насчет того, чтобы ваша аннотация @Stub расширяла аннотацию @Component? Как @Service или @Repository.

Вы будете сканировать свои bean-компоненты с помощью обычного сканирования контекста Spring, вы можете сохранить свою пользовательскую аннотацию, и вам не нужно будет вручную регистрировать свои bean-компоненты.

Пример из @Service:

{@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any
     */
    String value() default "";

}}
person rodrigobartels    schedule 20.06.2012
comment
К сожалению, изменить Stub на самом деле невозможно, так как я не управляю этим, но даже если бы это было так, как бы я загрузил bean-компоненты по их именам? Например, если я аннотировал компонент-заглушку с помощью @Stub("myStub"), как я упоминал в комментарии к другому ответу. Моя фабрика постпроцессоров в настоящее время регистрирует bean-компоненты Stub, используя это значение имени, чтобы позже их можно было получить с его помощью. - person Tyler Treat; 20.06.2012