2016-03-08 51 views
5

Próbuję owinąć sobie głowę czymś tutaj: Wstrzykiwanie tylko działa na pierwszej warstwie z mojej aplikacji, ale następnie zatrzymuje się i wszystkie właściwości adnotacji @Inject mają wartość null w obiektach zwróconych przez moją implementację wzorca fabrycznego. Czytam dużo o ludziach mających problemy z uzyskaniem CDI do pracy z JAX-RS, ale to nie jest mój problem. Mam wrażenie, że brakuje mi adnotacji lub nie widzę drzewa przed wszystkimi drzewami (tak jak tu mówimy) ;-)CDI nie działa w obiektach utworzonych na podstawie implementacji wzorca fabrycznego

Edytowanie: Czy przykładowy projekt z kodem wysłałem tutaj, aby dwukrotnie sprawdzić. Teraz zdaję sobie sprawę, że nad uproszczeniem: w rzeczywistości używam wzoru fabrycznego Factory w celu uzyskania mojej usługi, która może przerwać zarządzany kontekst. Zobacz powiększony przykład:

Chodźmy.

pierwsze warstwy: JAX-RS Application dobre

@RequestScoped 
@Path("/somePath/someResource") 
public class SomeResource { 
    @Inject 
    ISomeServiceFactory someServiceFactory; 

    @POST 
    @Produces(MediaType.APPLICATION_JSON) 
    @Consumes(MediaType.APPLICATION_JSON) 
    public SomeResponse someMethod(@PathParam("foo") final String foo) { 
     ISomeService myService = someServiceFactory.getService(ServiceCatalog.valueOf(foo)); // works, we jump in there! 
     myService.someMethod(); 
    } 

} 

public enum ServiceCatalog { 
    STANDARD("standard"), ADVANCED("advanced"), FOO("foo"); 
    // ... 
} 

uszkodzony fabryka usługa, która jest wybranie implementację w oparciu o znanej wartości parametrów (Enum) od reszty API Call:

public interface ISomeServiceFactory { 
    public ISomeService getService(ServiceCatalog serviceType); 
} 

@Stateless 
public class SomeServiceFactory implements ISomeServiceFactory { 
    public ISomeService getService(ServiceCatalog serviceType) { 
    if(serviceType.equals(ServiceCatalog.FOO)) { 
     return new FooService(); // will break CDI context 
    } else if (...) { 
     // ... 
    } else { 
     return new DefaultService(); // will also break CDI context 
    } 
    } 
} 

Druga warstwa: Niektóre EJB, kłopot tutaj

// Interface: 

public interface ISomeService { 
    public void someMethod(); 
} 

// Implementation: 

@Stateless 
public class SomeService implements ISomeService { 
    @Inject 
    private ISomeDao someDao; // this will be null !!! 

    @Override 
    public void someMethod() { 
    someDao.doSomething() // exception thrown as someDao == null 
    } 
} 

Dao, który ma być wstrzykiwany

public interface ISomeDao { 
    public void someMethod(); 
} 

@Stateless 
public class SomeDao implements ISomeDao { 
    public void someMethod() {} 
} 

Teraz przy starcie WebSphere Liberty mówi mi (między innymi powiązaniami ...) to:

com.ibm.ws.ejbcontainer.runtime.AbstractEJBRuntime 
I CNTR0167I: The server is binding the com.ISomeDao interface of the 
SomeDao enterprise bean in the my.war module of the my application. 
The binding location is: java:global/my/SomeDao!com.ISomeDao 

Mam fasoli. xml:

<beans 
    xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" 
    bean-discovery-mode="all"> 
</beans> 

Wygląda na to, że nowa usługa SomeService() łamie wszystko, czy można n jak wdrożyć fabrykę w sposób umożliwiający CDI w dalszej części drogi? Dzięki.

+0

Jeśli jest to istotne, uruchamiam produkt WebSphere Liberty 8.5.5.8 z zainstalowanym następującym zestawem funkcji: [servlet-3.1, jndi-1.0, jaxrs-2.0, cdi-1.2, webProfile-7.0, ejbLite- 3.2, ejbHome-3.2, ejbRemote-3.2, javaee-7.0, ejb-3.2, ...] i mają javaee-api 7, cdi-api 1.2, javax.inject 1 w moim maven pom.xml –

+0

lista funkcji jest zdecydowanie relewantne - polecam aktualizację twojego pytania przynajmniej częścią '' twojego serwera.xml –

+0

Zgodnie z życzeniem: ' javaee-7.0 jaxrs-2.0 localConnector-1,0 cdi-1,2 jsonp-1,0 ' –

Odpowiedz

2

W zmienionym pytaniu wykazano, że w serwisie internetowym nie ma faktycznie wtyczki EJB, jest ona nowsza pośrednio przez fabrykę.

Obiekt ma tylko wtrysk CDI wykonanego w momencie, gdy pojemnik tworzy obiekt, sam będąc gdzieś wstrzyknięty lub będący jednym z zarządzanych komponentów EE.

Netto, nie można utworzyć nowego komponentu EJB ani żadnego komponentu CDI i mieć w nim żadnych usług CDI.

+0

Tak, masz rację, to też wymyśliłem. Czytam teraz, jak uruchomić fabrykę w ramach ograniczeń CDI. Musiałbym mieć coś z @Produce, który zwraca implementację opartą na wartości wyliczeniowej. Ciekawy, jak to urzeczywistnić w najbardziej elegancki sposób. Do tego czasu dziękuję za twój wkład. –

+0

Nie sądzę, że wiemy z tego pytania, jakiego rodzaju próbujesz dokonać, nie tylko wstrzykując EJB według typu. Ale kolejnym najprostszym jest kwalifikatory typu +. – covener

+0

Tak, potrzebujesz klasy producenta, która może produkować wystąpienia twojej klasy. Oto przykład: http://buraktas.com/cdi-dependency-injection-producer-method-example – user1697575