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");