Подтвердить что ты не робот

Spring создает два beans из одного класса с помощью аннотаций

Я могу создать из двух beans из одного класса java, используя конфигурацию xml, используя следующий код:

    <context:component-scan base-package="some.package"/>

    <bean id="dependentBean" class="some.package.DependentBean">
        <property name="firstBean" ref="firstBean"/>
    </bean>

    <bean id="firstBean" class="some.package.Handler">
        <constructor-arg index="0" ref="service"></constructor-arg>
        <property name="defaultUrl" value="url/first"></property>
    </bean>

    <bean id="secondBean" class="some.package.Handler">
        <constructor-arg index="0" ref="service"></constructor-arg>
        <property name="defaultUrl" value="url/second"></property>
    </bean> 

Моя цель - перенести firstBean и secondBean в конфигурацию на основе java, например:

package some.package;

@Configuration
public class Configuration {

    @Bean(name="firstBean")
    public Handler firstHandler(Service service){
        Handler handler= new Handler(service);
        handler.setDefaultTargetUrl("url/first");
        return handler;
    }


    @Bean(name="secondBean")
    public Handler secondHandler(Service service){
        Handler handler = new Handler(service);
        handler.setDefaultTargetUrl("url/second");
        return handler;
    }
}

Но когда контекст начинает загрузку spring выдает следующее исключение:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'firstBean' is defined

Тем не менее он работает в этом случае:

package some.package;

    @Component
    public class Filter{

        private Handler handler;

        @Autowired
        public Filter(@Qualifier("secondBean") Handler handler) {
             this.handler = handler;
        }

    }

Выполнение обработчика:

public class Handler {

    private Service service;

    @Autowired
    public Handler(Service service) {
        this.service = service;
    }

}
4b9b3361

Ответ 1

@Autowired всегда по типу. Но у вас есть два обработчика в вашей конфигурации. Поэтому, когда вы пытаетесь autwire класса обработчика, вы должны указать квалификатор. Этим spring может разрешить, какой экземпляр будет введен. Else, spring выдает сообщение об ошибке NoSuchBeanDefinitionFoundError. Ожидаемый найден два.

Надеюсь, что это поможет.

Ответ 2

Из Spring Docs, раздел 5.9.3:

Если вы намереваетесь выражать введенную аннотацией инъекцию по имени, не используйте в основном @Autowired, даже если технически можно ссылаться на имя bean через значения @Qualifier. Вместо этого используйте аннотацию JSR-250 @Resource, которая семантически определена для идентификации конкретного целевого компонента по его уникальному имени, причем объявленный тип не имеет отношения к процессу сопоставления.

Вот пример этого в разделе 5.9.5, но для вашего кода класс Фильтр должен выглядеть так:

package some.package;

@Component
public class Filter {

    private Handler handler;

    @Resource(name="secondBean")
    public Filter(Handler handler) {
         this.handler = handler;
    }

}