2

I want to create multiple beans based upon the value in configuration file. I have the bean ready in configuration file. But how can I create multiple beans.

My current configuration file.

@Configuration
public class JMSConfig {

    @Bean
    public DefaultMessageListenerContainer listenerContainers() {
        ...
    }
}

My idea to achieve the requirement. If I use prototype scope I will get a new bean each time I ask for that bean. So I added prototype.

@Configuration
public class JMSConfig{
    @Value("${value}")
    private long value;

    @Bean
    @Scope("prototype")
    public DefaultMessageListenerContainer listenerContainers() {
        .....
    }

     for(i = 0; i < value; i++){
         //get a new bean
     }
}

The important challenge I am facing is

  1. How to get a new bean(the part I commented)
  2. How can I trigger the 'for' loop as I start the application Do I need to do this part in another class or how can I achieve this requirement?
Alex Saunin
  • 976
  • 1
  • 8
  • 15
hars
  • 127
  • 4
  • 17

1 Answers1

0

If you want to get your beans right out from the Spring-Boot main method. Use smth like this:

@SpringBootApplication
public class MyApplication {

    public static void main(final String[] args) {
        ApplicationContext context = SpringApplication.run(MyApplication.class, args);

        final int totalBeans = context.getEnvironment().getProperty("totalBeans")
        final List<DefaultMessageListenerContainer> beans = new ArrayList<>();
        for (int i = 0; i < totalBeans; i++) {
            beans.add(context.getBean(DefaultMessageListenerContainer.class));
        }

    }

}

beans list in this particular example contains N objects of DefaultMessageListenerContainer.class.

"totalBeans" argument in getProperty method is the name of appropriate property in application.yml file, defining N total count of beans.

BTW: It might be better not to create beans from main method (if it is not a mandatory requirement):

In this case, you can define List<DefaultMessageListenerContainer> bean in your @Configuration class and inject it later using standard Spring approach:

@Value("totalBeans")
private int totalBeans;

@Bean 
public List<DefaultMessageListenerContainer> beans() {
    final List<DefaultMessageListenerContainer> beans = new ArrayList<>();
    for (int i = 0; i < totalBeans; i++) {
        beans.add(new DefaultMessageListenerContainer());
    }
    return beans;
}

...

@Autowired private List<DefaultMessageListenerContainer> beans;
Alex Saunin
  • 976
  • 1
  • 8
  • 15
  • I want to do this in config file, if I do in main method, my application will not work, because it sees that DMLC are not present and it will fail – hars Oct 26 '17 at 14:21
  • So everytime I call listenerContainers() method , I get a new bean? – hars Oct 26 '17 at 15:10
  • Generally not exactly the bean. When you call `listenerContainers()` guess you create a `new DefaultMessageListenerContainer(...)` object. It becomes a bean when you define it as a bean using @Bean annotation. A bean with `prototype` scope will return a different instance every time it is **requested** from the container. Defining a bean with `singleton` scope means the container creates a single instance of that bean, and all requests for that bean name will return the same object, which is cached. Any modifications to the object will be reflected in all references to the bean – Alex Saunin Oct 26 '17 at 15:29
  • Hey Alex, can you look at this ?https://stackoverflow.com/questions/46959420/how-to-call-predestroy-for-a-bean-declared-with-bean-annotation – hars Oct 26 '17 at 17:03
  • @hars Answered by link above. BTW, if you're satisfied with an answer feel free to accept it – Alex Saunin Oct 27 '17 at 07:20