2014-09-24 16 views
13

Potrzebuję uzyskać klasę prototypów z singleton. Zauważyłem, że metoda wstrzyknięcia jest drogą do zrobienia, ale tak naprawdę nie wiem jak używać adnotacji spring @Lookup.Jak korzystać z adnotacji Spring @Lookup?

Jestem nowy w zastrzyku zależności i zdecydowałem się na konfigurację adnotacji, więc chciałbym kontynuować w tym kierunku.

Dowiedziałem się, że adnotacja @Lookup została dodana dopiero niedawno (https://spring.io/blog/2014/09/04/spring-framework-4-1-ga-is-here), ale nie mogę nigdzie znaleźć sposobu jej użycia.

Więc tutaj jest uproszczony przykład

klasa Konfiguracja:

@Configuration 
@Lazy 
public class ApplicationConfiguration implements ApplicationConfigurationInterface { 

    @Bean 
    public MyClass1 myClass1() { 
    return new ContentHolderTabPaneController(); 
    } 

    @Bean 
    @Scope("prototype") 
    public MyClass2 myClass2() { 
    return new SidebarQuickMenuController(); 
    } 
} 

I tu jest klasa przykład:

public class MyClass1 { 
    doSomething() { 
    myClass2(); 
    } 

    //I want this method to return MyClass2 prototype 
    public MyClass2 myClass2(){ 
    } 
} 

Jak mam to zrobić z @Lookup adnotacji?

Odpowiedz

24

Przed nałożeniem @Lookup adnotacji do sposobu public MyClass2 myClass2(), przeczytać w @Lookup's Javadoc:

pojemnik na wygeneruje podklasy runtime zawierającego klasę danej metody za pośrednictwem CGLIB, dlatego takie metody lookup może pracować tylko na ziarna, które kontener tworzy instancje za pomocą zwykłych konstruktorów (tzn. metody wyszukiwania nie mogą zostać zastąpione na ziarnach zwróconych z fabrycznych metod, które nie mogą być dynamicznie dostarczane dla nich podklas).

Więc usunąć następującą metodę factory deklarację styl fasolowa z ApplicationConfiguration:

@Bean 
    public MyClass1 myClass1() { 
    return new ContentHolderTabPaneController(); 
    } 

i dodać @Component adnotacji pozwolić Wiosna instancji fasola (również dodać @Lookup adnotacji metody):

@Component 
public class MyClass1 { 
    doSomething() { 
    myClass2(); 
    } 

    //I want this method to return MyClass2 prototype 
    @Lookup 
    public MyClass2 myClass2(){ 
    return null; // This implementation will be overridden by dynamically generated subclass 
    } 
} 

Teraz usuń komponent bean myClass1 z kontekstu, a jego metoda myClass2 powinna zostać zastąpiona/overridde n, aby za każdym razem otrzymać nową fasolkę prototypu.


Aktualizacja:

Korzystanie deklaracja metoda fabryki

To nie jest trudne do wdrożenia @Lookup uwagami metoda ("metody lookup"). Bez @Lookup i utrzymując klasa konfiguracja niezmienione, teraz MyClass1 wygląda (w rzeczywistości Wiosna generuje podobny wdrożenie w podklasie jeśli @Lookup użyto):

public class MyClass1 { 
    doSomething() { 
    myClass2(); 
    } 

    //I want this method to return MyClass2 prototype 
    @Autowired 
    private ApplicationContext applicationContext; 
    public MyClass2 myClass2() { 
     return applicationContext.getBean(MyClass2.class); 
    } 
} 

Wiosna wstrzykuje ApplicationContext dla Ciebie.

+0

Dziękuję. I czy istnieje sposób użycia tej fasoli MyClass1 w deklaracji w stylu fasoli w stylu fabryki jako zależności? – Miljac

+0

Następnie wdrażamy własną metodę wyszukiwania - na szczęście jest to bardzo łatwe. Zobacz moją aktualizację odpowiedzi. – qingbo

+3

Ale czy nie jest to taki rodzaj pokonania celu DI, ponieważ Bean musi być świadomy kontenera DI? – Miljac

5

Jeśli nie jesteś na wiosnę 4.1 można używać zamiast wtrysku dostawcy:

public class MyClass1 { 
    @Autowired 
    private Provider<MyClass2> myClass2Provider; 

    doSomething() { 
    MyClass2 myClass2 = myClass2(); 
    myClass2.fooBar() 
    } 

    public MyClass2 myClass2(){ 
    return myClass2Provider.get(); 
    } 
} 

Jest DI, IoC, unika klasy abstrakcyjne i definicji xml dla metod wyszukiwania.

+3

'javax.inject.Provider', aby być precyzyjnym – alaster

+0

To zadziałało świetnie w moich testach jednostkowych. Nie mogłem uruchomić usługi @Lookup – rince

Powiązane problemy