как сделать рьяную одиночную инициализацию в Guice - PullRequest
0 голосов
/ 24 января 2019

Как выполнить активную инициализацию синглтона в 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 голосов
/ 11 февраля 2019

В методе configure() вашего модуля Guice свяжите класс как нетерпеливый синглтон.

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

}

В любом случае вам нужно убедиться, что вы на самом делевозможность ввести необходимые значения в поставщик или метод @Provides.

...