如何在Guice中进行渴望的单例初始化

时间:2019-01-24 20:12:09

标签: java spring guice

如何在Guice中进行急切的单例初始化。我在春季以下列方式完成了工作:

<!-- 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>

但是在吉斯(Guice):

如果我这样做:

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

    }

这不起作用。 在Guice中,我希望在服务启动后立即实例化StaggeredScheduler。注意:StaggeredScheduler构造函数会启动调度程序的启动(该代码不在我的控制范围内)

请提出建议。

1 个答案:

答案 0 :(得分:0)

在Guice模块的configure()方法中,将类绑定为渴望的单例。

protected void configure() {
    bind(StaggeredScheduler.class).toProvider(StaggeredSchedulerProvider.class).asEagerSingleton();
}

并实现Provider<StaggeredScheduler>。例如:

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

一个更快捷,更肮脏的技巧是将其添加到您的Guice模块中:

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

}

在任何一种情况下,您都需要确保实际上能够将所需的值注入Provider或@Provides方法中。