Home > Software design >  How do I create multiple Spring beans of the same type without defining each one
How do I create multiple Spring beans of the same type without defining each one

Time:05-10

I've seen a lot of workaround-looking things regarding what I'm trying to do using BeanDefinitionRegistryPostProcessor, but I wondered if there was a way to tap directly into Spring's bean creation API to override some behavior.

What I would like to see is something like this (note the 's' in @Components):

@Components(prefix="myBean-", numberOfInstances="${myapp.mybean.numberOfInstances}")
public class MyBean {

  private final MyService myService;

  public MyBean(final MyService myService) {
    this.myService = myService;
  }

  @Scheduled(fixedDelayString = "${myapp.mybean.fixedDelay}")
  public myJob() {
    System.out.println("I'm working!");
  }
}

I am basically looking for the same functionality of @Component where I can specify how many instances to make and just have the name generated.

As I mentioned before, the only way I have found to do this sort of thing (specifically for scheduled tasks now) is to use the BeanDefinitionRegistryPostProcessor to create the instances or create a custom SchedulingConfigurer to configure the tasks manually without using Spring beans, which means all the Runnable's dependencies have to be wired into the SchedulingConfigurer, and that just feels dirty.

Is this even possible--to add a new annotation to scan for and invoke some other way to create the beans?

CodePudding user response:

Actually I'm wondering why u wanna do this. According to the IOC philosophy, beans should be delegated to container and clients don't need to care about beans' lifecycles. That's why Spring provides @Scope to support different bean scopes like singleton/request/session. So I don't think it a good way to control the specific number of a certain bean, besides, beans should theoretically be non-stateful, thus a single instance is fairly enough.

CodePudding user response:

Prototype scoped beans will be provided as a new instance for each request to the container.

@Component
@Scope("prototype")
public class MyBean {

  private final MyService myService;
  public MyBean(final MyService myService) {
    this.myService = myService;
  }

  // ...
}

// Get two separate instances
MyBean bean1 = (MyBean)applicationContext.getBean("myBean");
MyBean bean2 = (MyBean)applicationContext.getBean("myBean");
  • Related