2012-01-22 44 views
1

這裏是一個非常奇怪的行爲,使用EJB豆:奇怪的EJB行爲還是我錯過了什麼?

@Local 
public interface Provider { 
    void test(); 
} 

@Local 
public interface ExtProvider extends Provider { 
    void test2(); 
} 

public abstract class AbstractProvider implements Provider { 
    @Override 
    void test(){ System.out.println("Hello strange " + getTech()); } 
    protected abstract String getTech();   
} 

public abstract class ExtAbstractProvider extends AbstractProvider implements ExtProvider { 
    @Override 
    void test2() { System.out.println("Hello from " + getName());} 
    @Override 
    String getTech() { return "extended EJB";} 
    protected abstract String getName(); 
} 
@Stateless 
public class ProviderBean extends AbstractProvider { 
    @Override 
    protected String getTech() { return "EJB";} 
} 

@Stateless 
public class ExtProviderBean extends ExtAbstractProvider { 
    @Override 
    protected String getName() { return "ext provider";} 
} 

根據上面的代碼,如果我寫:

@EJB Provider provider; // should inject an instance of ProviderBean 
@EJB ExtProvider extProvider; // should inject an instance of ExtProviderBean 

但兩部作品沒有一個!有人會說,在這個例子中,EJB不知道每次創建哪個實例,因爲有兩個實現Provider的實例。而奇怪的是:

public class ExtProviderBean extends ExtAbstractProvider implements ExtProvider 
public class ProviderBean extends AbstractProvider implements Provider 

在這種情況下,代碼的工作:如果我們聲明兩個bean,因爲它僅適用。問題是我們必須明確地定義一個實現bean實現了接口,即使它是從抽象實現隱式定義的。我錯過了什麼,或者這是一個限制?

+0

我不確定EJB 3.1,但我猜容器只會爲實際的EJB類創建隱式本地接口,或者使用直接實現的接口 - 尤其是因爲AbstractProvider沒有註解(在類級別),因此可能被認爲是一個EJB。 – Thomas

+0

我有兩個問題:我可以註釋一個抽象類嗎? EJB容器不應該知道Provider接口將ProviderBean作爲實現,畢竟這是通過擴展AbstractProvider來隱式定義的,因此當其他bean實現時:@EJB Provider prv;會注入一個ProviderBean的實例。當然這裏有個問題:容器可以注入一個ExtProviderBean的實例,因爲這是一個Provider。但有沒有其他的方法可以解決這個問題,而不需要聲明這個類來明確地實現它的本地接口(從我的角度來看這有點奇怪)? – Elvis

+0

正如我所說我不是JEE 6專家,但在JEE 5(因此EJB 3.0)中,依賴注入會拒絕同一個EJB接口的多個實現(至少這是我的經驗)。你可以通過提供更多的信息來做到這一點(例如,使用'beanName'屬性),但我希望使用顯式接口。順便說一句,「不起作用」的含義很模糊,你能提供更多的信息嗎? – Thomas

回答

0

我剛剛通過this SO question閱讀,我認爲提供的答案也適用於您的情況。

我剛引述答案的一部分,從而使EE規範:

@Stateless 
public class A implements Foo { ... } 

@Stateless 
public class B extends A implements Bar { ... } 

假設Foo和Bar是本地業務接口並沒有 相關的部署描述符,會話bean,曝露出本地 業務接口Foo和會話bean B暴露本地業務 接口Bar,但不是Foo。會話bean B需要明確地將 包括在其應用的該接口的暴露視圖的集合中。

相關問題