简体   繁体   中英

how to do eager singleton initialization in Guice

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM