EJB继承与Java继承不同

尽管EJB继承有时使用Java继承,但它们并不总是相同的。 就像您在我以前的文章中可以读到的那样 ,EJB不必实现任何接口即可公开业务接口。
另一种方法也是正确的-仅仅是因为EJB实现了某个接口或扩展了其他EJB并不意味着它公开了全部或任何视图。

假设我们要具有一些公开远程业务接口的基本EJB。 然后,我们想扩展此EJB并覆盖远程业务方法。
没什么好看的,对吧? 但是,让我们看一些示例。

远程业务接口:
public interface RemoteA {
    void remoteA();
}
基础EJB:
@Stateless 
@Remote(RemoteA.class) 
public class SuperclassEJB implements RemoteA {   
    public void remoteA() {
        // Some basic code that can be overriden.
    }
}

上面的SuperclassEJB是我们的基础EJB。 它通过一种方法公开了一个远程业务接口。 现在,让我们转到EJB的子类:

案例1 – Java继承

@Stateless 
public class SubclassEJB1 extends SuperclassEJB {
    // 'remoteA' is not EJB business method. EJB inheritance is strictly for implementation reusing.
}

SubclassEJB1是一个EJB –可以肯定。 但是它公开了哪些接口? 因为EJB组件必须显式定义其定义的业务接口,所以我们的EJB根本没有任何实际的业务方法! 它是新的,全新的无接口视图EJB。

这意味着,如果在您的代码中,您将执行以下操作:

  • @EJB SubclassEJB1 myEJB它将注入没有业务方法的无接口视图EJB。
  • @EJB(name='SubclassEJB1') RemoteA myEJB它将拒绝进行此注入,因为RemoteA不是我们EJB的业务接口。

有趣的是–如果不是使用@EJB进行容器注入,而是进行如下查找:

RemoteA subclassEJB1 = (RemoteA) initialContext.lookup('java:module/SubclassEJB1');
subclassEJB1.remoteA();

它不会引发任何异常并正确调用remoteA()方法。 为什么? 因为我们真正查找的是EJB的无接口视图。 然后,我们将其转换为RemoteA (从纯Java角度来看这是正确的),并调用了无接口视图方法。 我想您会同意这会造成很大的混乱–我们没有使用远程接口,而是最终正确调用了本地bean方法。

案例2 –接口实现的Java继承

@Stateless 
public class SubclassEJB2 extends SuperclassEJB implements RemoteA {
    // 'remoteA' is correctly exposed as EJB business method BUT as an implicit local i-face. 
    // Method implementation is correctly inherited.
}

现在看起来真的很奇怪。 我们的EJB扩展了其他EJB并实现了远程业务接口,对吗? 好吧,不完全是。 我们正在实现纯Java RemoteA接口。 该接口本身没有@Remote批注, SuperclassEJB也没有。 这意味着我们RemoteA公开为本地业务接口 。 这是我以前的文章中讨论的EJB的默认行为之一。

这意味着,如果在您的代码中,您将执行以下操作:

  • @EJB(name='SubclassEJB2') RemoteA myEJB它将使用本地业务接口。 搞砸了,你不觉得吗?

案例3 –具有接口实现和视图声明的Java继承

@Stateless 
@Remote(RemoteA.class) 
public class SubclassEJB3 extends SuperclassEJB {
    // Method 'remoteA' is correctly exposed as EJB business method (thanks to @Remote on EJB). 
    // Method implementation is correctly inherited.
}

这是EJB扩展的正确示例。 我们已经通过Java继承正确地重用了实现,实现了EJB远程业务接口,并使用@Remote公开了它。 甚至不需要implements子句– @Remote就足够了。 但是,@ @Remote部分至关重要。

这意味着,如果在您的代码中,您将执行以下操作:

  • @EJB(name='SubclassEJB3') RemoteA myEJB将正确使用远程业务接口。

结论

如您所见,EJB继承有时可能不如预期的那么容易。 它要求您了解组件和视图定义的基础。 默认情况下,组件继承显然是为了代码重用,而不是组件扩展。 没有这些知识,您可能会遇到一些非常奇怪和令人沮丧的问题。 所有示例都在JBoss AS 7.1.1上进行了测试。

参考: EJB继承不同于Java继承,来自Piotr Nowicki主页博客上的JCG合作伙伴 Piotr Nowicki。

翻译自: https://www.javacodegeeks.com/2013/03/ejb-inheritance-is-different-from-java-inheritance.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值