2012-01-22 45 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需要明确地将 包括在其应用的该接口的暴露视图的集合中。

相关问题