Reputation: 11
How to do eager singleton initialization in Guice. I have done in spring in the following way:
<!-- Scheduler to run the artifact metadata refresher. -->
<bean id="springTest" class="org.springframework.beans.factory.config.MethodInvokingBean"
scope="singleton">
<property name="targetObject" ref="initializer"/>
<property name="targetMethod" value="createScheduler" />
<property name="arguments">
<list>
.... define arguments
/***final Runnable artifactRefresherTask,
final long fixedInitialDelayInSecs,
final int maxRandomScheduledDelayInSecs,
final long schedulePeriodInSecs,
final long awaitTerminationInSecs
**/
</list>
</property>
</bean>
But in Guice:
if I do this :
@Singleton
@Inject
public void provideArtifactRefresherScheduler(
final Runnable artifactRefresherTask,
final long fixedInitialDelayInSecs,
final int maxRandomScheduledDelayInSecs,
final long schedulePeriodInSecs,
final long awaitTerminationInSecs
) {
new StaggeredScheduler(
test" /* name of the scheduler.*/,
StaggeredScheduler.ScheduleStrategy.FIXED_RATE /* scheduler strategy to be used */,
fixedInitialDelayInSecs,
maxRandomScheduledDelayInSecs,
schedulePeriodInSecs,
artifactRefresherTask,
true,
awaitTerminationInSecs);
}
This does not work. In Guice, I want my StaggeredScheduler to be instantiated as soon as the service starts. Note: StaggeredScheduler constructor initiates the start of the scheduler( that code is not in my control)
Please suggest.
Upvotes: 0
Views: 4079
Reputation: 7669
In the configure()
method of your Guice module, bind the class as an eager singleton.
protected void configure() {
bind(StaggeredScheduler.class).toProvider(StaggeredSchedulerProvider.class).asEagerSingleton();
}
And implement Provider<StaggeredScheduler>
. For example:
public class StaggeredSchedulerProvider implements Provider<StaggeredScheduler> {
@Inject
public StaggeredSchedulerProvider(final Runnable artifactRefresherTask,
final long fixedInitialDelayInSecs,
final int maxRandomScheduledDelayInSecs,
final long schedulePeriodInSecs,
final long awaitTerminationInSecs) {
this.fixedInitialDelayInSecs = fixedInitialDelayInSecs;
this.maxRandomScheduledDelayInSecs = maxRandomScheduledDelayInSecs;
this.schedulePeriodInSecs = schedulePeriodInSecs;
this.artifactRefresherTask = artifactRefresherTask;
this.awaitTerminationInSecs = awaitTerminationInSecs;
}
public StaggeredScheduler get() {
new StaggeredScheduler(
"test", /* name of the scheduler.*/
StaggeredScheduler.ScheduleStrategy.FIXED_RATE, /* scheduler strategy to be used */
fixedInitialDelayInSecs,
maxRandomScheduledDelayInSecs,
schedulePeriodInSecs,
artifactRefresherTask,
true,
awaitTerminationInSecs);
}
}
A more quick and dirty hack is to add this to your Guice Module:
@BindingAnnotation
@Retention(RUNTIME)
private @interface PrivateBindingAnnotation {}
protected void configure() {
bind(StaggeredScheduler.class).annotatedWith(PrivateBindingAnnotation.class).to(StaggeredScheduler.class).asEagerSingleton();
}
@Provides
@Singleton
public StaggeredScheduler provideArtifactRefresherScheduler(
final Runnable artifactRefresherTask,
final long fixedInitialDelayInSecs,
final int maxRandomScheduledDelayInSecs,
final long schedulePeriodInSecs,
final long awaitTerminationInSecs) {
new StaggeredScheduler(
test" /* name of the scheduler.*/,
StaggeredScheduler.ScheduleStrategy.FIXED_RATE /* scheduler strategy to be used */,
fixedInitialDelayInSecs,
maxRandomScheduledDelayInSecs,
schedulePeriodInSecs,
artifactRefresherTask,
true,
awaitTerminationInSecs);
}
In either case, you will need to make sure that you are actually able to inject the required values into the Provider or the @Provides
method.
Upvotes: 2