Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring creates two beans from one class using annotations

Tags:

java

spring

I have can create from two beans from one java class using xml configuration using following code:

    <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> 

My goal is move firstBean and secondBean to java based configuration like this:

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;
    }
}

But when context begins loading spring throws the following exception:

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

Nevertheless it works in this case:

package some.package;

    @Component
    public class Filter{

        private Handler handler;

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

    }

Handler implementation:

public class Handler {

    private Service service;

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

}
like image 857
fashuser Avatar asked Jul 05 '13 14:07

fashuser


People also ask

Can we create multiple beans of same class in Spring?

Yes, you can do it with a help of your custom BeanFactoryPostProcessor implementation. Here is a simple example. Suppose we have two components. One is dependency for another.

Can we create 2 beans of same class?

The limitation of this approach is that we need to manually instantiate beans using the new keyword in a typical Java-based configuration style. Therefore, if the number of beans of the same class increases, we need to register them first and create beans in the configuration class.

Can we use @component and @bean in same class?

In the component classes, we can use any valid annotation along with @Bean method and it's parameters, exactly the same way we use them in @Configuration classes (e.g. @Lazy, @Qualifier, @Primary etc).


1 Answers

@Autowired is always by type. But you have two Handlers in your configuration. So when you try to autowire the handler class, you have to specify the qualifier. By this spring can resolve which instance to inject. Else, spring throws the error showing NoSuchBeanDefinitionFoundError. Expected one found two.

Hope that helps.

like image 141
pravat Avatar answered Oct 19 '22 16:10

pravat