Issue
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?
Update
Thanks to @vince for helping me realize I don't need a separete bean for each job; I just have to configure the singleton multiple times into the FixedDelayTask
.
@Component
public class MyBean {
private final MyService myService;
public MyBean(final MyService myService) {
this.myService = myService;
}
// Remove @Scheduled here since we have to configure multiple
// instances manually. This is where it would be nice to specify
// how many jobs of the same type you want.
// @Scheduled(fixedDelayString = "${myapp.mybean.fixedDelay}")
public myJob() {
System.out.println("I'm working!");
}
}
@Configuration
@EnableScheduling
public class MyBeanTaskConfiguration implements SchedulingConfigurer {
private final MyBean myBean;
public MyBeanTaskConfiguration(MyBean myBean) {
this.myBean = myBean;
}
@Override
public void configureTasks(final ScheduledTaskRegistrar taskRegistrar) {
for (int i = 0; i < numberOfWorkers; i++) {
taskRegistrar.scheduleFixedDelayTask(
new FixedDelayTask(
myBean,
repeatIntervalMs,
repeatIntervalMs / numberOfWorkers * i + startDelayMs
)
);
}
}
}
Solution
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.
Answered By - vince
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.