本文主要介绍在JBOSS EAP 6.2(或者JBOSS AS7)中模块是如何贯穿EJB实现的始终。延续上一博文《认识模块的使用》的话题继续聊JBOSS做为模块申明式容器的这一特性在EJB实现中的完全贯彻。
JBOSS EAP(AS7)中默认的EJB是3.1版本遵循JSR318规范。EJB从3.0开始已经全面引入Annotation的概念,3.0以前的EJB需要在XML文件里面对Bean所做的配置都能通过标签的方式在代码中实现。同时,之前为了工厂模式而做的双接口Home和Remote已经被一个业务接口所取代。由于Entity Bean的概念已经从EJB中拿出放到了JPA规范中,所以这里只介绍Session Bean最基本的Annotation方式的实现,为后文提供知识基础。
Session Bean由两部分组成:一个业务接口和一个具体实现业务的JAVA类。
业务接口是一个普通的Java接口Interface。
可以被声明为@Local或者@Remote,区别就是标明这个EJB的可见度。
@Local标明这是一个只在同一个容器范围内的应用可见的Session bean
@Remote只要能与这台主机通讯的地方都可以调用这个Session bean。
<span style="font-size:18px;">public interface AssessContentBean extends BaseBean<AssessContent> { public List<AssessContent> queryContentByTemplateId(String templateId); public boolean deleteAll(Object[] ids); }</span>
在类名的上方使用@Stateless或者@Stateful来指明这个Session Bean是否有状态。
需要注意的一点变化是:与EJB3.0不同的是EJB3.1的JNDI有很大变化,原本在EJB3.0的时候@Stateless(name=”StudentAssessResultBeanImpl”),在客户端可以使用initContext.lookup(“StudentAssessResultBeanImpl”)查到这个bean。
但是EJB3.1的JNDI规范是
java:global[/<app-name>]/<module-name>/<bean-name>[!<fully-quali?fied-interface-name>]其中WAR包名称app-name,JAR包名称module-name,自定义Bean名称bean-name,接口的全地址名称fully-quali?fied-interface-name。
直接上一个最简单的无状态Bean的实例:
<span style="font-size:18px;">@Stateless(name="StudentAssessResultBeanImpl") @Remote(StudentAssessResultBean.class) @TransactionManagement(TransactionManagementType.CONTAINER) @TransactionAttribute(TransactionAttributeType.REQUIRED) public class StudentAssessResultBeanImpl extends BaseBeanImpl<StudentAssessResult> implements StudentAssessResultBean { @EJB(beanName = "StudentAssessResultEao") private StudentAssessResultEao studentAssessResultEao; @Override public BaseEao getBaseEao() { // TODO Auto-generated method stub23 return this.studentAssessResultEao; } }</span>
【EJB学习内容小扩展】
下面列举一些常用的标签,学习完它们大部分的应用都够了。
@Stateless
@Remote
@Local
@LocalBean
@EJB
@Resource
@Inject
@Stateful
@Init
@PostConstruct
@PreDestroy
@PrePassivate
@PostActivate
@Remove
以上介绍的都是服务端EJB的代码,Client端在下一篇博文《让人又爱又恨的EJB3.1 JNDI》介绍JNDI的时候会有更深入的介绍。
<span style="font-size:18px;">@Stateless(name="StudentAssessResultBeanImpl") @Remote(StudentAssessResultBean.class) @TransactionManagement(TransactionManagementType.CONTAINER) @TransactionAttribute(TransactionAttributeType.REQUIRED) public class StudentAssessResultBeanImpl extends BaseBeanImpl<StudentAssessResult> implements StudentAssessResultBean { @EJB(beanName = "StudentAssessResultEao") private StudentAssessResultEao studentAssessResultEao; @Override public BaseEao getBaseEao() { // TODO Auto-generated method stub23 return this.studentAssessResultEao; } }</span>
commonClass被打成jar包,放置在jboss-eap-6.1\modules\com\xx\ngoss\xxx\commonClass\main中,并配置module.xml文件如下,
<span style="font-size:18px;"><span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.1" name="com.xx.ngoss.xxx.commonClass"> <dependencies> <module name="javax.api"/> <module name="javax.transaction.api"/> <module name="org.jboss.remote-naming"/> <module name="org.jython"/> </dependencies> <resources> <resource-root path="CommonClass.jar"/> </resources> </module></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.1" name="org.jython"> <dependencies> <module name="javax.api"/> </dependencies> <resources> <resource-root path="jython.jar"/> </resources> </module></span></span>
LogManger是实现EJB业务的地方,最终部署的时候会被放置到jboss-eap-6.1\standalone\deployments中部署。与之前的JBOSS AS不同之处在于:JBOSS EAP 6.1(AS7)中一个EJB项目对JBOSS模块的依赖需要指明在MANIFAST.MF文件中。LogManager/src/META-INF/MANIFEST.MF文件如下配置:
Manifest-Version: 1.0 Dependencies: com.xx.ngoss.xxx.commonClass, com.xx.ngoss.xxx.logManagerCommon, org.jboss.log4j.logmanager Class-Path:
这样就指明了EJB Project对JBOSS EAP 6.1中配置好的模块com.xx.ngoss.xxx.commonClass,com.xx.ngoss.xxx.logManagerCommon和org.jboss.log4j.logmanager的依赖。才完成整个EJB在JBOSS中的配置工作。剥离业务实现,这个日志组件的配置包括以下三步:
系统自带包,第三方包,自定义包全都变为模块,模块与组建之间需要指明依赖关系,同时EJB项目也需要指明依赖关系到JBOSS EAP中的组件上。JBOSS EAP 6.1中组件的概念可谓是深入骨髓。
本文首先介绍了最简单的EJB 3.1的实现,随后引入一个实例类说明JBOSS模块是如何配置到EJB项目、用户制作的lib、第三方的lib、系统lib之间来清楚的指明依赖关系的。这种设计为JBOSS容器优化带来了可行性。也在JBOSS EAP 6.1的启动与重启速度中得到了充分的证明。
但从开发人员的角度出发,虽然开发环境中JBOSS的起降性能有很大提升,但是这种所有lib都需要配置为module的方式没有原来直接仍到lib中的方式容易实现,由于module可能被配置在$JBOSS_EAP$/modules目录下的任何一级目录下,有的或许系统里面已经有了,有的需要引入,引入到什么位置,都由开发人员自行决定。这样的自由度一方面给开发人员带来了额外的工作量,另一方面如果多个开发人员一起开发,不同的模块引入相同的包到了不同级别的目录下,从而引发冲突。
总结
综上所述,模块申明式容器这一新特性,从性能的角度来看值得欣赏,但对于开发人员来说是利弊参半,我们慢慢的深入体会吧。