2013-07-17 11 views
10

Na podstawie parametrów przekazanych do metody, należy wybrać jeden z wielu komponentów bean Spring, które są implementacjami tej samej klasy, ale skonfigurowane z różnymi parametrami.Jak wybrać instancję Spring bean w środowisku wykonawczym

E.g. jeśli użytkownik A wywoła metodę, muszę wywołać dooFoo() na fasoli A, ale jeśli to użytkownik B, to muszę wywołać tę samą metodę, tylko na ziarnie B.

Czy istnieje "Springierowy" sposób robienia tego poza przyklejeniem wszystkich ziaren na mapie i wyprowadzeniem klucza z parametrów przekazanych do mojej metody?

+0

Rozwiązaniem zasugerowanym przez kolegę było, że '@Apiowired Map ' zapełni się ID komponentu bean jako kluczem - być może to może być najgorsze rozwiązanie. –

+0

Zobacz podobny wpis. http://stackoverflow.com/a/24525715/3796723 – linusdsunil

Odpowiedz

2

Wygląda na to, że chcesz ServiceLocator używając kontekstu aplikacji jako rejestru.

Zobacz klasę wsparcia do tworzenia kluczy serwisowych ServiceLocators do nazw fasoli bez łączenia kodu klienta ze sprężyną.

Inną opcją jest użycie konwencji nazewnictwa lub konfiguracji opartej na adnotacjach.

na przykład, zakładając, że przypisuje się do nich Usługi za pomocą @ExampleAnnotation("someId"), można użyć czegoś takiego, jak poniższy lokalizator usług, aby je pobrać.

public class AnnotationServiceLocator implements ServiceLocator { 

    @Autowired 
    private ApplicationContext context; 
    private Map<String, Service> services; 

    public Service getService(String id) { 
     checkServices(); 
     return services.get(id); 
    } 

    private void checkServices() { 
     if (services == null) { 
      services = new HashMap<String, Service>(); 
      Map<String, Object> beans = context.getBeansWithAnnotation(ExampleAnnotation.class); 
      for (Object bean : beans.values()) { 
       ExampleAnnotation ann = bean.getClass().getAnnotation(ExampleAnnotation.class); 
       services.put(ann.value(), (Service) bean); 
      } 
     } 
    } 
} 
-1

Jeśli mówimy o ziarnach (A, B) o SessionScope to żaden problem, zostaną one wybrane poprawnie.

public class BusinessLogic { 

    private BaseClassOfBeanAandB bean; 

    public void methodCalledByUserAorB() { 
    bean.doFoo(); 
    } 

} 
+0

Dzięki. W tym przypadku nie ma sesji HTTP, a komponenty bean są zbyt ciężkie, aby utworzyć instancję na żądanie. –

+0

Więc jak możesz się różnić między użytkownikiem A i B? Na podstawie parametru przekazanego do metody? – Manuel

+0

Tak. Istnieje pewne wstępne uwierzytelnianie, więc przekazujemy nam identyfikatory użytkowników (w rzeczywistości kilka parametrów, które łączą się, aby stworzyć tożsamość, ale to nie ma znaczenia). –

2

Trzymanie ich na mapie brzmi dobrze. Jeśli jest to mapa zarządzana przez Spring (używając util:map lub w konfiguracji Java), to jest to lepsze niż tworzenie jej gdzie indziej, ponieważ wtedy Spring posiada wszystkie odniesienia do obiektów i może właściwie zarządzać ich cyklem życia.

9

Stoimy w obliczu tego problemu w naszym projekcie, a my rozwiązujemy go poprzez klasę podobną do fabrycznej. Klasa klient -the który potrzebował fasoli na runtime- miał wystąpienie fabryki, który został wstrzyknięty poprzez wiosny:

@Component 
public class ImTheClient{ 

    @Autowired 
    private ImTheFactory factory; 

    public void doSomething(
      Parameters parameters) throws Exception{   
     IWantThis theInstance = factory.getInstance(parameters);   

    } 

} 

Więc instancja IWantThis zależy od wartości wykonawczego parametru parameters. Realizacja Fabryka idzie tak:

@Component 
public class ImTheFactoryImpl implements 
     ImTheFactory { 

    @Autowired 
    private IWantThisBadly anInstance; 
    @Autowired 
    private IAlsoWantThis anotherInstance; 

    @Override 
    public IWantThis getInstance(Parameters parameters) { 
     if (parameters.equals(Parameters.THIS)) { 
      return anInstance; 
     } 

     if (parameters.equals(Parameters.THAT)) { 
      return anotherInstance; 
     } 

     return null; 
    } 
} 

Więc instancja fabryka posiada odniesienie do obu posible wartościach klasy IWantThis, będących IWantThisBadly i IAlsoWantThis obie implementacje IWantThis.

+0

Ładne jedno rozwiązanie! :) – grozandrei

Powiązane problemy