2012-12-10 8 views
5

Mam dwie fasole, Rodzic i Dziecko. Element potomny, który zadeklarowałem jako zakres prototypu.
Chcę, aby nowy obiekt podrzędny był używany do wywoływania metody dowolnego dziecka w klasie nadrzędnej. Na przykład w poniższym przykładzie chcę, aby instrukcja 1 wywoływała metodę sayHi dla różnych obiektów podrzędnych i instrukcji 2 w przypadku różnych obiektów podrzędnych.Fasola oznaczona zakresem prototypu nie działa wiosną

Jednym ze sposobów jest wdrożenie ApplicationContextAware i pobranie nowego obiektu podrzędnego za pomocą context.getBean("") przed wywołaniem metody dowolnego dziecka. Ale nie chcę tego robić.

Czy jest jakaś inna alternatywa?

@Component 
public class Parent{ 

    @Autowired 
    Child child; 

    public void sayHello(){  
     child.sayHi();   -------------- (1) 
    } 

    public void sayHello1(){  
     child.sayHi1();   --------------- (2) 
    } 
} 

@Component 
@Scope(value=BeanDefinition.SCOPE_PROTOTYPE) 
public class Child{ 

    public void sayHi(){ 
     System.out.println("Hi Spring 3.0"); 

    } 

    public void sayHi1(){ 
     System.out.println("Hi1 Spring 3.0 ");  
    } 

} 
+0

Jeśli to konfiguracja xml wtedy użyć metody lookup-metoda, ale to nie jest jeszcze dostępna w adnotacjach, wierzę. http://stackoverflow.com/questions/3891997/how-to-do-spring-lookup-method- injection- with-annotations –

Odpowiedz

2

Chyba trzeba dokonać new Child się za każdym razem, czy rzeczywiście używać kontekstu sprężyny, aby uzyskać świeże ziarna.

Wiosna utworzy nową instancję tylko wtedy, gdy będzie musiała coś wstrzyknąć (w przypadku prototypu). Kiedy jesteś w klasie, jesteś skutecznie poza zasięgiem wiosny.

Oto podobnym stanowisku: @Scope("prototype") bean scope not creating new bean

http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s04.html#beans-factory-scopes-prototype części 4.4.2 i 4.4.3 są istotne.

0

Nie możesz tego zrobić. Po ustawieniu ApplicationContext do elementu potomnego zostanie wstawiony tylko jeden komponent bean. Dla każdego rodzica zostanie utworzone nowe dziecko.

Rzecz w tym, że rodzic ma tylko jedno dziecko, więc twoje 2 metody wywołają tylko te metody potomne.

Co dokładnie próbujesz osiągnąć? Jestem pewien, że istnieje odpowiednie rozwiązanie.

10

Poprawka polega po prostu na oznaczeniu fasoli prototypowej jako proxy o ustalonym zakresie, co oznacza, że ​​po wstrzyknięciu komponentu o mniejszym zakresie do większego zakresu (jak w przypadku, gdy prototyp jest wstrzykiwany w pojedynczą) wtedy proxy komponentu bean zostanie wprowadzone do większego zakresu, a gdy metody komponentu bean zostaną wywołane przez serwer proxy, proxy zrozumie zakres i zareaguje odpowiednio.

@Component 
@Scope(value=BeanDefinition.SCOPE_PROTOTYPE, proxyMode=ScopedProxyMode.TARGET_CLASS) 
public class Child{ 

Oto reference

Innym rozwiązaniem mogłoby być wykorzystanie coś takiego odnośnika zastrzyk metoda opisana here

1

zakres Prototyp oznacza Wiosna daje nową Child obiektowi za każdym razem, kiedy poprosić o jeden (przez wstrzyknięcie lub jawne pobranie fasoli z kontekstu aplikacji). W swojej klasie Parent, prosiłeś tylko raz o Child, więc masz tylko jedną. Jeśli chcesz dwa różne Child obiektów w swojej Parent, następnie autowire dwa:

@Component 
public class Parent{ 

    @Autowired 
    Child child; 

    @Autowired 
    Child child1; 

    public void sayHello(){  
     child.sayHi(); 
    } 

    public void sayHello1(){  
     child1.sayHi1(); 
    } 
}