这篇文章将讨论使用批注定义EJB视图的可能方法(最后我将只提到使用EJB部署描述符)。我将重点介绍最新的EJB 3.1视图,这些视图将省略旧的本地,远程和本地接口。 因此,我们可以选择:
- 远程业务界面视图,
- 本地业务界面视图,
- 无接口视图
我不会讨论这些视图之间的功能差异,而将重点放在定义它们的可能方法上。
本地业务界面视图
-
EJB正在实现此接口。
@Local public interface LocalA {void localA(); }
@Stateless public class MeineEJB implements LocalA {@Overridepublic void localA() {} }
优点:
- 您不必在EJB中指定接口类型。 您只需“用Java实现”它,其余的工作就由容器完成。
- 有关接口类型的信息牢固地附加在接口上,因此对于其他开发人员来说可能更容易理解。
- 由于有了Java
implements
子句,您可以使用javac或IDE来确保实现了所有EJB业务方法。
缺点:
- 现在,您的界面已与EJB技术紧密结合(导入
javax.ejb.*
包。)现在,您必须为API客户端提供使用它所需的库。
-
具有
EJB必须定义应该作为本地业务接口公开的接口(这是默认设置,请参见第3点。)
public interface LocalA {void localA(); }
@Stateless @Local(LocalA.class) public class MeineEJB implements LocalA {@Overridepublic void localA() {} }
优点:
- 有关接口类型的信息是松散耦合的。 您可以将API交付给客户端,而不必关心EJB语义。 如果您将其隐藏在外立面上,则最终用户(甚至是开发人员)甚至不必知道它在幕后使用EJB技术。
- 由于有了Java
implements
子句,您可以使用javac或IDE来确保实现了所有EJB业务方法。
缺点:
- 您的EJB现在必须使用
@Local
注释定义其所有业务接口,因此这是您的附加工作。 不仅实现接口,还需要记住声明EJB正在公开它。 (从javac角度来看)没有什么可以阻止您将接口放入@Local
批注中,而该接口实际上并未由EJB实现。
-
EJB正在实现它。
因为它是EJB唯一实现的接口,所以容器假定它必须是本地业务接口。 如果EJB实现多个接口,那么容器将无法识别哪个接口是您的本地业务接口。
public interface LocalA {void localA(); }
@Stateless public class MeineEJB implements LocalA {@Overridepublic void localA() {} }
优点:
- 具有上述第一种和第二种方法的所有优点。
缺点:
- 它假定EJB容器的默认行为以及开发人员对此的了解。 如果你使用一个以上的EJB图。它不会起作用。 此外,它甚至不会 ,如果你的EJB正在实施一个以上的工作界面(不一定是EJB视图)。
-
具有
在这种情况下,有趣的是,因为您没有使用Java
implements
子句,所以实际上接口和EJB中的方法可以具有不同的签名。 任何此类不匹配都会导致容器抛出异常。 另请注意,业务接口方法实现上缺少@Override
批注。 这是因为我们没有使用Java术语实现任何接口。public interface LocalA {void localA(); }
@Stateless @Local(LocalA.class) public class MeineEJB {public void localA() {} }
优点:
- 有关接口类型的信息是松散耦合的。 您可以将API交付给客户端,而不必关心EJB语义。 如果您将其隐藏在外立面上,则最终用户(甚至是开发人员)甚至不必知道它在幕后使用EJB技术。
缺点:
- 具有上面讨论的第二种方法的所有缺点。
- 您声明为
@Local
接口的某些方法未实现的知识在很大程度上取决于使用的IDE。 Intellij IDEA会将其标记为错误,但AFAIR Eclipse则不会。 - 在我看来,这是最重要的缺点的组合,因此是定义EJB视图的最差的方法。
远程业务界面视图
本地业务接口视图的情况1、2和4对远程业务接口视图也有效。 点号 3是一个例外。 容器将永远不会承担有关远程接口的任何事情。 如果EJB正在实现某个接口,并且未定义接口的类型,则它将始终假定它是本地的。
无接口视图
我确定阅读完上述部分后,您将能够了解使用以下两种方法定义无接口EJB视图的利弊。 因此,我将不在这里讨论它们。
-
EJB注释为
该EJB可以但不一定要实现某些接口(普通Java或业务本地/远程接口)。
@LocalBean
仅对EJB类有效。@Stateless @LocalBean public class MeineEJB {public void localMethod() {} }
-
EJB没有任何特殊的注释。
该容器假定,如果将一个类注释为EJB,但未实现任何接口,并且没有任何与视图相关的注释–它将公开一个无接口视图。
@Stateless public class MeineEJB {public void localMethod() {} }
EJB部署描述符(ejb-jar.xml)
前面的所有部分都在考虑使用批注定义的EJB视图。 您还可以使用部署描述符( ejb-jar.xml
)定义EJB视图。 例:
public interface LocalA {void localA();
}
public interface RemoteA {void remoteA();
}
@Stateless
public class MeineEJB {public void localA() {}public void remoteA() {}
}
<ejb-jar xmlns='http://java.sun.com/xml/ns/javaee' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd' version='3.1'><enterprise-beans><session><ejb-name>MeineEJB</ejb-name><business-local>com.piotrnowicki.remotelocalejb.LocalA</business-remote><business-remote>com.piotrnowicki.remotelocalejb.RemoteA</business-remote><local-bean/></session></enterprise-beans>
</ejb-jar>
上面的代码和DD定义了一个EJB,它公开了三个视图(本地业务,远程业务和无接口)。 在语义上与以下内容相同:
@Stateless@Local(LocalA.class)@Remote(RemoteA.class)@LocalBeanpublic class MeineEJB {public void localA() {}public void remoteA() {}}
参考:在Piotr Nowicki主页博客上,我们的JCG合作伙伴 Piotr Nowicki 定义了EJB 3.1视图(本地,远程,无接口) 。
翻译自: https://www.javacodegeeks.com/2013/03/defining-ejb-3-1-views-local-remote-no-interface.html