Powiedzmy, że mam EJB z następującą konfiguracją:
package com.main.notsimulated
@Singleton
@EJB(name = "java:/sample/MainOne", beanInterface = MainOne.class)
public class MainOne {}
Ten ejb musi być obecny dla innegoelementy rozmieszczone do pracy. Jednak używanie tego modułu MainOne nie jest dla mnie zbyt wykonalne w środowisku testowym. Zamiast tego wolałbym wstrzyknąć własną niestandardową wersję w czasie wykonywania.
package com.main.simulated
@Singleton
@EJB(name = "java:/sample/MainOne", beanInterface = MainOne.class)
public class MainOne {}
(Uwaga, są to dwa różne pliki jar)
Dlatego mój pomysł jest taki, spróbujmy zastąpić plikobecnie wdrażane z niestandardową wersją w locie. Powodem, dla którego chcę to zrobić, jest to, że nie chcę w ogóle zmieniać wersji niesymulowanej, ani w żaden sposób wpływać na konsumentów ejb. Oznacza to, że wszystko, co obecnie robi konsument, to szuka tej konkretnej nazwy jndi i wykonuje odrzucenie i rzutowanie na określony interfejs.
Spojrzałem na to stanowisko w nadziei, że dowiem się, czy moja klasa MainOne pochodzi zcom.main.simulated może eksmitować aktualnie utworzoną instancję klasy MainOne. Jednak wybrana odpowiedź stwierdza, że nie można programowo rozpocząć ani zatrzymać ejb. Też się temu przyjrzałem stanowisko, ale jest to bardziej praktyczny przewodnik, w jaki sposób możemy wstrzykiwać te ziarna w naszych telefonach.
W związku z tym moje pytanie brzmi: czy moja druga implementacja (com.main.simulated) może w jakiś sposób „zastąpić” inny komponent i zapewnić, że wersja com.main.notsimulated nigdy nie zostanie wykonana?
Odpowiedzi:
0 dla odpowiedzi № 1Wdrażanie dwóch klas z tym samym powiązaniem tooczywiście niemożliwe. Próbując to zrobić, otrzymasz wiążący wyjątek. Jednak w przeciwieństwie do moich oryginalnych badań programowe wiązanie fasoli jest całkowicie możliwe. W związku z tym rozwiązanie, w jaki sposób można „przejąć” stare powiązanie i zastąpić je nowym, jest następujące: (Uwaga, zastąp nazwy klas tym, czego potrzebujesz)
package com.main.simulated
@Startup
@Singleton
public class MainOne {
@PostConstruct
private void rebindClass() throws NamingException {
final Context context = new InitialContext();
context.rebind("java:/sample/MainOne", this);
}
// other methods that will be called
}
Trzy ważne rzeczy dotyczące tej klasy to:Usunięcie adnotacji @EJB, adnotacji @Startup i ponowne powiązanie kontekstu. @Startup zapewnia wywołanie metody @PostConstruct, gdy nasz kontener ładuje naszą klasę. W takim przypadku metoda ponownie wiąże klasę pod kątem wartości. W związku z tym jest to lokalizacja porwania.
Mam nadzieję, że to pomaga komuś.