2016-03-08 26 views
5

我想繞過我的頭在這裏的東西:注入只有作品在我的應用程序的第一層,但它然後停止和所有@注入註釋屬性爲空從我的工廠模式實現中返回的對象中。我讀了很多有關讓CDI與JAX-RS一起工作的問題的人,但這似乎不是我的問題。我覺得我錯過了一些註釋,或者我沒有看到所有樹木前面的木材(正如我們在這裏所說的那樣);-)CDI不工作在從工廠模式實現創建的對象

編輯:使用我發佈的代碼做了一個示例項目在這裏仔細檢查。現在我意識到我過於簡化了:實際上我使用工廠模式來獲取我的服務,這可能會中斷託管上下文。請參閱增強示例:

我們走吧。

第一層:JAX-RS的應用,都好

@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"); 
    // ... 
} 

破碎服務工廠是基於已知的參數中選擇一個執行(枚舉)從REST API調用值:

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 
    } 
    } 
} 

第二層:一些EJB,這裏麻煩

// 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 
    } 
} 

是應該的道在運行時被注入

public interface ISomeDao { 
    public void someMethod(); 
} 

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

現在的WebSphere自由告訴我(其他綁定...中)這樣的:

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 

我有一個豆子。 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> 

看起來好像新的SomeService()打破了一切,你能建議嗎? ❖如何以CDI進一步實現工廠化?謝謝。

+0

如果相關,我運行在WebSphere Liberty 8.5.5.8上,安裝了以下功能集:[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,...]並且在我的maven pom.xml中有javaee-api 7,cdi-api 1.2,javax.inject 1 –

+0

功能列表是definetely相關 - 我建議至少用你的server.xml中的'部分更新你的問題。 –

+0

按照要求:' javaee-7.0 jaxrs-2。0 localConnector-1.0 CDI-1.2 JSONP-1.0' –

回答

2

在修改後的問題中,您會發現實際上並沒有注入到Web服務中的EJB,它是通過工廠間接新建的。

對象只有在容器創建對象時才執行CDI注入,或者通過本身被注入某個地方,或者它是託管EE組件之一。

網絡,你不能新建一個EJB或任何CDI bean,並有任何CDI服務。

+0

是的你是對的,這也是我的想法。我正在閱讀如何在CDI約束下啓動和運行工廠。我需要用@Produce來返回一個基於枚舉值的實現。好奇如何實現這個最優雅的方式。在此之前感謝您的意見。 –

+0

我不認爲我們從這個問題的背景知道你試圖做什麼樣的選擇,而不僅僅是按類型注入EJB。但下一個最簡單的是類型+限定符。 – covener

+0

是的,你需要一個可以產生你的課程實例的生產者類。 這裏是例子:http://buraktas.com/cdi-dependency-injection-producer-method-example – user1697575