Подтвердить что ты не робот

Когда использовать javax.inject.Provider в Spring?

Что делается довольно просто:

@Inject
private Provider<ProductService> productService;

Служба продукта доступна через productService.get(), а .get() разрешит экземпляр из контекста Spring для каждого вызова.

Но когда его использовать? И где?

Мое главное использование usecase довольно просто: когда я получаю циклические зависимости, поставщик помогает разрешить зависимость во время выполнения. Но это выглядит немного случайным, если вы просто выбросите его, просто не сможете создать свой контекст, вызванный циклической зависимостью.

Существуют ли какие-либо известные шаблоны об использовании Провайдеров?

4b9b3361

Ответ 1

Этот интерфейс эквивалентен org.springframework.beans.factory.ObjectFactory<T>, который обычно используется, чтобы избежать вызовов BeanFactory.getBean() в клиентском коде при поиске экземпляров прототипов. Часто используется с ObjectFactoryCreatingFactoryBean для получения прототипов beans, полученных с помощью BeanFactory.

пример из ObjectFactoryCreatingFactoryBean javadocs:

<beans>

   <!-- Prototype bean since we have state -->
   <bean id="myService" class="a.b.c.MyService" scope="prototype"/>

   <bean id="myServiceFactory"
       class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
     <property name="targetBeanName"><idref local="myService"/></property>
   </bean>

   <bean id="clientBean" class="a.b.c.MyClientBean">
     <property name="myServiceFactory" ref="myServiceFactory"/>
   </bean>

</beans>

С Providers вместо этого вы можете использовать ProviderCreatingFactoryBean.

Другой вариант решения одной и той же проблемы (с использованием наследования вместо композиции) - это метод поиска метода поиска

Ответ 2

В cdi Провайдеры используются для ввода объектов с меньшей областью в область с расширенным охватом bean, например. если для сеанса с узлами bean требуется доступ к объекту с областью запроса, он вводит провайдера, а затем метод, который выполняется в запросе, вызывает provider.get(), чтобы получить ссылку на локальную переменную на соответствующий объект с областью запроса.

Учитывая следующее:

@RequestScoped
public class Bean1 {
    void doSomething();
}

Следующее будет использовать экземпляр Bean1, связанный с первым запросом в сеансе, для использования Bean2, независимо от того, какой запрос вызывает Bean2.doSomething():

@SessionScoped
public class Bean2 {
    @Inject Bean1 bean;

    public void doSomething() {
        bean.doSomething();
    }
}

Далее будет использоваться экземпляр bean, связанный с конкретным запросом, который в настоящее время вызывает Bean3.doSomething(), т.е. другой bean для каждого запроса:

@SessionScoped
public class Bean3 {
    @Inject Provider<Bean1> bean;

    public void doSomething() {
        bean.get().doSomething();
    }
}