2012-05-10 18 views
19

W CDI można zdefiniować obiekt, który daje elementy określonego typu, przy użyciu:Co Wiosna odpowiednik dla CDI Instancji lub Guices Provider

 
@Inject 
Instance<MyObject> myObjectInstance; 
//... 
MyObject myObjectInstance.get(); 

Podobnie w Guice można zrobić:

 
@Inject 
Provider<MyObject> myObjectInstance; 
//... 
MyObject myObjectInstance.get(); 

Zastanawiam się, czy istnieje podobna konstrukcja na wiosnę, lub trzeba użyć ApplicationContext w celu uzyskania odniesienia?

Odpowiedz

15

Więc po wielu kopanie wokół okazało się, że wiosna obsługuje JSR-330. Ten JSR definiuje prosty interfejs API - cała specyfikacja jest dosłownie właśnie tym interfejsem API - który standaryzuje kilka interfejsów, adnotacji i zachowań zależnych od zależności.

W przeciwieństwie do interfejsu Spring FactoryBean, interfejs javax.inject.Provider nie generuje wyjątku podczas pobierania odwołania do komponentu bean. Co więcej, nadal będziesz musiał zdefiniować to FactoryBean w pewnym miejscu (odczytać klasę XML lub @Configuration, a to jest nieoptymalne).

Z powodu błędu, w aktualnym Spring 3.1.1, javax.inject.Provider nie działa. To działa pod numerem wiosną 3.1.0.

W celu wykorzystania go ty prosty konieczność uwzględnienia słoik javax.inject - jeśli używasz Maven można:

<dependency> 
     <groupId>javax.inject</groupId> 
     <artifactId>javax.inject</artifactId> 
     <version>1</version> 
    </dependency> 

Wiosna wykryje go, i od tego momentu można po prostu:

@Inject 
Provider<MyObject> myObjectInstance; 
//... 
MyObject myObjectInstance.get(); 

podobnie jak w przykładzie Guice, ponieważ jest to ten sam interfejs API.

Pomimo mojego poprzedniego komentarza do Konstantina, wiosna powoduje, że dostawca sam tworzy usługę. (Testowałem to w stosunku do Spring 3.1.1 i działałem na to Spring Provider regression issue)

+0

+1 Dobra odpowiedź. –

+1

Obawiam się, że między dostawcą <> a wystąpieniem <> są znaczące różnice (mam nadzieję, że się mylę). Po pierwsze: Instance implementuje Iterable i ma to duży wpływ na to, jak z niego korzystasz. Na przykład. regularnym użyciem dla mnie jest deklarowanie instancji @Inject xxx ... więc będę mógł iterować poprzez instancje każdej klasy implementującej interfejs bez znajomej nazwy klasy. Chcę wiedzieć, jak to zrobić, korzystając z dostawcy. – Rafael

+0

'Instance <>' nie jest częścią JSR-330 i nie jest częścią Spring. Problemem, który wówczas miałem, było uzyskanie fasoli prototypowej (zależnej od niektórych zmiennych kontekstowych), bez konieczności wstrzymywania samego kontekstu aplikacji. –

2

Brzmi jak FactoryBean

+0

Niezupełnie. Aby móc zautomatyzować 'FactoryBean', potrzebujesz do tego rzeczywistej implementacji. Z tego, co mogę powiedzieć, powinienem użyć 'ObjectFactoryCreatingFactoryBean', ale brzmi to jak zbyt wiele pracy bez żadnego powodu. –

+0

A co z metodą lookup z scope = "prototype"? W ten sposób: http://stackoverflow.com/a/10358248/1385087 –

+0

Problem polega na tym, że muszę zmienić XML (staram się zrobić większość moich ziaren za pomocą adnotacji) dla każdej instancji "Provider". Zauważyłem, że Spring obsługuje JSR-330, a więc także interfejs Providera, z tym, że nie tworzy tych fasoli na bieżąco, trzeba tworzyć te fasole na własną rękę - w ten sposób całkowicie mija się z celem. Ponadto nie ma adnotacji typu lookup, więc muszę zmienić kod XML i utworzyć nową klasę dla każdej fasoli? –