Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to get multiple instances of same bean in spring?

By default, spring beans are singletons. I am wondering if there is a way to get multiple instances of same bean for processing.

Here is what I do currently

    @Configuration
    public class ApplicationMain { 

     @Value("${service.num: not configured}")
    private int num;

    //more code

@PostConstruct
public void run(){

        for (int i = 0; i < num ; i++) {
                    MyService ser = new MyService(i);
                    Future<?> tasks = executor.submit(ser);
                }

    }
}

Here is the Service class

    public class MyService implements Runnable {

    private String name;

    public Myservice(int i){

    name=String.ValueOf(i);

    }
  }

I have simplified my usecase here. I want to have MyService as spring bean and get as many as possible based on configuartion (which is num) in the above for-loop? wondering how that is possible.

Thanks

like image 785
brain storm Avatar asked Feb 21 '17 21:02

brain storm


People also ask

Can we have two beans of same type in Spring?

The default autowiring is by type, not by name, so when there is more than one bean of the same type, you have to use the @Qualifier annotation.

Can we use @qualifier and @bean together?

By using the @Qualifier annotation, we can eliminate the issue of which bean needs to be injected. By including the @Qualifier annotation, together with the name of the specific implementation we want to use, in this example Foo, we can avoid ambiguity when Spring finds multiple beans of the same type.

Can we have 2 beans with same name?

Bean Overriding Spring beans are identified by their names within an ApplicationContext. Therefore, bean overriding is a default behavior that happens when we define a bean within an ApplicationContext that has the same name as another bean. It works by simply replacing the former bean in case of a name conflict.


2 Answers

First you'll have to make MyService a Spring bean. You can do this by annotating the class with @Component. Next, as you say, Spring beans are Singletons by default, so this can be changed with one more annotation - @Scope("prototype").

A prototype bean scope means that each time you ask Spring for an instance of the bean, a new instance will be created. This applies to Autowiring, asking the application context for the bean with getBean(), or using a bean factory.

like image 113
Luke Avatar answered Oct 14 '22 21:10

Luke


Here is a simple example of how to register a desired number of beans of the same type

@Configuration
public class MultiBeanConfig implements ApplicationContextAware {

    @Value("${bean.quantity}")
    private int quantity;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        for (int i = 0; i < quantity; i++) {
            ((ConfigurableApplicationContext)applicationContext).getBeanFactory()
                    .registerSingleton("my-service-" + i, new MyService());
        }
        assert(applicationContext.getBeansOfType(MyService.class).size() == quantity);
    }

    class MyService {

    }
}
like image 26
bart.s Avatar answered Oct 14 '22 22:10

bart.s