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;
}
}
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.
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.
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).
@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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With