冷月葬花魂 发表于 2015-1-18 11:10:20

JAVA网页编程之POJO使用架构:Spring与EJB 3.0的对照

不得不提一下的是:.net是看到java红,而开发出来的工具。架构  爱因斯坦已经说过:"每件事物都应当尽量复杂,而不是更复杂"。切实其实,对迷信真谛的寻求都是为了简化实际的基本假定,如许我们才干处置真正贫苦的成绩。企业级软件的开辟也是如许的。
  简化企业级软件开辟的关头是供应一个埋没了庞大性(比方事件、平安性和永续性)的使用框架。优秀计划的框架组件能够提拔代码的反复利用(reuse)才能,进步开辟效力,从而失掉更好的软件质量。可是,今朝J2EE1.4中的EJB2.1框架组件被人们广泛以为是计划较差的和过于庞大的。Java开辟者对EJB2.1很不满,他们已实验了多种别的的用于两头件服务传送的办法。最有目共睹的,上面两个框架组件已引发开辟者的伟大乐趣和主动的反应。它们极可能成为将来企业级Java使用程序可供选择的框架组件。
  ・Spring框架组件是一个盛行的,可是非尺度的开放源代码框架组件。它次要是由Interface21Inc.公司开辟和把持的。Spring框架组件的架构是基于依附注进(DI)计划形式的。Spring能够独自地大概与现有的使用程序服务器一同事情,它大批地利用XML设置文件。
  ・EJB3.0框架组件是一个尺度的框架组件,由Java社区构造(JCP)界说,并遭到一切支流的J2EE厂商撑持。预公布的EJB3.0标准的开放源代码和贸易完成都能够在JBoss和Oracle上看到了。EJB3.0大批利用Java正文(annotation)。
  这两个框架组件的中心计划理念是不异的:二者的方针都是把两头件服务传送给松懈耦合的复杂新式Java对象(POJO)。这些框架组件经由过程在运转时截取实行内容或向POJO注进服务对象,把使用程序服务与POJO绑缚在一同。POJO自己不体贴绑缚的历程,而且对框架组件几近没有依附。其了局是,开辟者能够聚焦于营业逻辑,团体能够在没有框架组件的情形下测试他们的POJO。别的,因为POJO不必要从框架组件中承继或完成框架组件接口,开辟者创建承继布局和构建使用程序的时分都有高度的天真性。
  可是,只管二者的计划理念是不异的,它们传送POJO服务时却接纳了完整分歧的办法。只管今朝已出书了大批的图书和文章来把Spring或EJB3.0与EJB2.1举行对照,可是它们都没有对Spring与EJB3.0之间的差别举行仔细的研讨。在本文中,我将研讨Spring和EJB3.0框架组件之间的关头差别,并会商它们的优弱点。本文的主题也能够使用在别的一些名望稍小的企业级两头件框架组件上,由于它们都聚焦于"松懈耦合的POJO"计划。我但愿本文可以匡助你选择切合需求的最好的框架组件。
  厂商有关性(Independence)
  开辟者选择某种Java平台的一个最主要的来由就是该平台的厂商有关性。EJB3.0是一个开放的、尺度的、具有厂商有关性的平台。EJB3.0标准是由企业级Java整体中一切支流开放源代码和贸易厂商开辟和撑持的。EJB3.0框架组件把开辟职员与使用程序服务器完成(implementation)断绝开来了。比方,只管JBoss的EJB3.0完成是基于Hibernate的,而Oracle的EJB3.0完成是基于TopLink的,可是开辟职员其实不必要进修Hibernate或TopLink的特别API,就能够让他们的使用程序在JBoss和Oracle上运转。厂商有关性把EJB3.0框架组件与别的的POJO两头件框架组件辨别开来了。
  可是,良多EJB3.0的品评家敏捷指出,在写这篇文章的时分,EJB3.0标准还没有到达终极宣布的版本。在EJB3.0被一切支流的J2EE厂商接纳之前大概还必要一到两年工夫。可是,即便你的使用程序服务器还没有天然地(natively)撑持EJB3.0,你仍是能够经由过程下载和安装一个"嵌进式的"EJB3.0产物,在服务器上运转EJB3.0使用程序。比方,JBoss嵌进式EJB3.0产物是开放源代码的,能够在任何与J2SE-5.0兼容的情况中(比方,在Java使用程序服务器中)运转。它如今正在举行beta测试。别的的厂商也大概很快公布他们的嵌进式EJB3.0产物,出格是用于标准的"数据永续性"部分的产物。
  另外一方面,Spring一向长短尺度的手艺,并且在能够预感的将来它仍旧是如许的。只管你能够把Spring框架组件与任何使用程序服务器一同利用,可是Spring使用程序都被"锁定"在Spring本身和你所选择的集成到Spring中的特定服务中了。
  ・只管Spring框架组件是一个开放源代码项目,可是它仍旧具有设置文件的专利XML格局和专利编程接口。固然,这类"锁定"产生在任何非尺度的产物上,Spring也不破例。可是它却形成了:你的Spring使用程序的临时保存才能依附于Spring项目自己(或Interface21Inc公司,它雇佣了年夜多半Spring中心开放职员)。别的,假如你利用任何Spring特定的服务,比方Spring事件办理器或SpringMVC,你就被"锁定"在这些API中了。
  ・Spring使用程序必要晓得背景的服务供应者。比方,关于数据延续(datapersistence)服务来讲,Spring框架组件为JDBC、Hibernate、iBatis和JDO利用了分歧的DAO和模板帮助类。因而,假如你但愿为Spring使用程序改换延续服务供应者(比方从JDBC切换到Hibernate),你就必需重构本人的使用程序代码,利用新的帮助类。
  服务集成
  从较高的条理看,Spring框架组件位于使用程序服务器和服务类库之上。其服务集成代码(比方数据会见模板和帮助类)位于框架组件当中,并表露给使用程序开辟者。与此分歧的是,EJB3.0框架组件被严密地集成到使用程序服务器中,服务集成代码被封装在尺度的接口中。
  其了局是,EJB3.0厂商能够主动地优化整体功能和开辟者体验。比方,在JBoss的EJB3.0完成中,利用EntityManager坚持实体BeanPOJO的时分,上层Hibernate对话事件会主动地与该挪用办法的JTA事件接洽在一同,当JTA事件提交的时分,它也会提交。假如利用复杂的@PersistenceContext正文(本文前面有一个例子),你乃至于能够在有形态的(stateful)对话bean中把EntityManager和它的上层Hibernate事件绑缚到一个使用程序事件上。该使用程序事件在一个对话中超过了多个线程,它在事件性的Web使用程序(比方多页面购物车)中长短常无效的。因为在JBoss中,EJB3.0框架组件、Hibernate和Tomcat严密集成,上述的复杂和集成的编程接谈锋得以完成。Oracle的EJB3.0框架组件和其上层Toplink延续服务之间的也完成了相似条理的集成。
  EJB3.0中集成服务的另外一个例子是聚集(clustering)撑持。假如你在服务器聚集中部署EJB3.0使用程序,那末一切的生效继续(fail-over)、负载平衡、散布式缓存和形态复礼服务都是能够主动地供给用程序利用的。上层聚集服务都埋没在EJB3.0编程接口前面,它们关于EJB3.0开辟职员来讲是完整通明的。
  在Spring中,优化框架组件与服务之间的交互操纵要坚苦很多。比方,为了利用Spring的宣布式事件服务来办理Hibernate事件,你必需在XML设置文件中显式地设置SpringTransactionManager和HibernateSessionFactory对象。Spring使用程序开辟者必需显式地办理跨多个HTTP哀求的事件。别的,要在Spring使用程序中利用聚集服务也没有复杂的路子。
  服务集成的天真性
  因为Spring中的服务集成代码是作为编程接口的一部分表露的,使用程序开辟者能够依据必要天真地集成服务。这个特征同意你集成本人的"轻量级"使用程序服务器。Spring最广泛的利用体例是把Tomcat和Hibernate"粘合"在一同来供应复杂的数据库驱动web使用程序。在这类情形下,Spring本身供应事件服务,Hibernate供应延续(persistence)服务--这类构造体例在Spring中创建了一个微型使用程序服务器。
  EJB3.0使用程序服务器没有付与你选择服务的天真性。在年夜多半情形中,你失掉一组事前包装好的特征,而你只必要个中的一部分。可是,假如使用程序服务器由形式化的外部计划主导(相似JBoss),那末你便可能把它分隔,往失落一些不用要的特征。在任何情形下,定制成熟的使用程序服务器都不是一个复杂的事变。
  固然,假如使用程序的局限超出了单节点,那末你大概必要绑缚来自一般使用程序服务器的服务(比方资本缓冲池、动静行列和聚集)。在整体的资本损耗方面,Spring办理计划与任何EJB3.0办理计划一样,都是"分量级"的。
  在Spring中,天真的服务集成使得我们更简单把仿造(mock)对象(而不是实践的服务对象)绑缚到使用程序,用于在容器内部举行单位测试。在EJB3.0使用程序中,年夜多半组件都是复杂的POJO,我们能够很简单地在容器内部测试这些它们。可是关于测试那些触及到容器服务的对象(比方延续EntityManager),我们保举在容器内测试,由于比起仿造对象的办法,它们更复杂、更固定、更准确。XML与正文的对照
从使用程序开辟者的角度来看,Spring的编程接口次要是基于XML设置文件的,而EJB3.0普遍利用了Java正文。XML文件能够表达庞大的干系,可是它们同时也很冗杂、固定水平也较低。正文复杂了然,可是在正文中我们却很难表达庞大的或条理的布局。
  Spring和EJB3.0关于XML或正文的选择是依附于这两个框架组件前面的架构的:因为正文只能保留相称少的设置信息,只要事后集成的框架组件(相似在框架组件中已完成了年夜多半准备事情)能够普遍地把正文作为设置选项。我们已会商过了,EJB3.0切合这类需求,而Spring作为一个通用的DI框架组件,不切合这个需求。
  固然,EJB3.0和Spring都在进修对方的最好特征,它们都在某个水平上撑持XML和正文。比方,在EJB3.0中XML设置文件是一个可选的重载机制,能够用于改动正文的默许举动。正文也能够用于设置某些Spring服务。
  熟悉XML和正文之间的区分的最好路子是经由过程示例。鄙人一部分,我们会看到Spring和EJB3.0是怎样为使用程序供应关头服务的。
<P>  宣布式服务(DeclarativeServices)

  Spring和EJB3.0都把运转时服务(比方事件、平安性、日记纪录、动静和定礼服务)绑缚到使用程序上。因为这些服务都没有间接地与使用程序的营业逻辑相干联,因而它们不由使用程序本身来办理。作为取代,这些服务是在运转时由服务容器(比方Spring或EJB3.0)通明地使用在程序上的。开辟者(或办理员)设置容器并告知容器怎样/甚么时分使用服务。

  EJB3.0利用Java正文设置宣布式服务,而Spring利用XML设置文件。在年夜多半情形下,关于这类服务,EJB3.0正文办法加倍复杂,加倍文雅。上面是一个在EJB3.0中给POJO办法使用事件服务的例子。

publicclassFoo{

@TransactionAttribute(TransactionAttributeType.REQUIRED)
publicbar(){
//实行某些操纵...
}
}

  你也能够在一个代码片段中界说多个属性,使用多个服务。上面是一个在EJB3.0中同时给POJO使用了事件和平安性服务的例子:

@SecurityDomain("other")
publicclassFoo{

@RolesAllowed({"managers"})
@TransactionAttribute(TransactionAttributeType.REQUIRED)
publicbar(){
//实行某些操纵...
}
}

  利用XML指定代码属性和设置宣布式服务大概招致冗杂的和不不乱的设置文件。上面是一个在Spring使用程序中使用XML元素给Foo.bar()办法使用一个十分复杂的Hibernate事件服务的例子:

<!--Setupthetransactioninterceptor-->
<beanid="foo"
class="org.springframework.transaction
.interceptor.TransactionProxyFactoryBean">

<propertyname="target">
<beanclass="Foo"/>
</property>

<propertyname="transactionManager">
<refbean="transactionManager"/>
</property>

<propertyname="transactionAttributeSource">
<refbean="attributeSource"/>
</property>
</bean>

<!--SetupthetransactionmanagerforHibernate-->
<beanid="transactionManager"
class="org.springframework.orm
.hibernate.HibernateTransactionManager">

<propertyname="sessionFactory">
<!--youneedtosetupthesessionFactorybeanin
yetanotherXMLelement--omittedhere-->
<refbean="sessionFactory"/>
</property>
</bean>

<!--Specifywhichmethodstoapplytransaction-->
<beanid="transactionAttributeSource"
class="org.springframework.transaction
.interceptor.NameMatchTransactionAttributeSource">

<propertyname="properties">
<props>
<propkey="bar">
</props>
</property>
</bean>

  假如你给统一个POJO增加多个拦阻器(interceptor,比方平安性拦阻器),那末XML的庞大水平会呈多少级数增加。Spring意想到了只利用XML设置文件的范围性,它如今撑持在Java源代码中利用Apache通用元数据指定事件属性。在最新的Spring1.2中,还撑持JDK-1.5款式的正文。假如你要利用事件元数据,就必要把下面的transactionAttributeSourcebean改动成AttributesTransactionAttributeSource示例,并增添与元数据拦阻器相干的分外设置。

<beanid="autoproxy"
class="org.springframework.aop.framework.autoproxy
.DefaultAdvisorAutoProxyCreator"/>
<beanid="transactionAttributeSource"
class="org.springframework.transaction.interceptor
.AttributesTransactionAttributeSource"
autowire="constructor"/>
<beanid="transactionInterceptor"
class="org.springframework.transaction.interceptor
.TransactionInterceptor"
autowire="byType"/>
<beanid="transactionAdvisor"
class="org.springframework.transaction.interceptor
.TransactionAttributeSourceAdvisor"
autowire="constructor"/>
<beanid="attributes"
class="org.springframework.metadata.commons
.CommonsAttributes"/>

  当你具有良多事件办法的时分,Spring元数据简化了transactionAttributeSource元素。可是它没有办理XML设置文件的基础成绩--冗杂和懦弱,仍是必要利用事件拦阻器、transactionManager和transactionAttributeSource。
<P>  依附注进(DependencyInjection)

  两头件容器的关头上风在于它们同意开辟者创建松懈耦合的使用程序。服务的客户端只必要晓得服务的接口。容器器具体的完成来初始化服务对象,并使客户端可以会见它们。这就同意了容器在分歧的服务虚现之间举行切换,而不必要改动接口或客户端代码。

  依附注进(DI)形式是完成松懈耦合的使用程序的最好的办法之一。它比旧办法(比方经由过程JNDI的依附查找或容器回调)更容易于利用、更文雅。利用DI的时分,框架组件充任创建服务对象的对象工场,并依据运转时设置,把这些服务对象注进使用程序POJO中。从使用程序开辟者的角度来看,当客户端POJO必要利用某种服务对象的时分,它们会主动地猎取该对象。

  Spring和EJB3.0都给DI形式供应了普遍的撑持,可是它们之间有一些深入的差别。Spring撑持一般的、可是庞大的、基于XML设置文件的DIAPI;EJB3.0经由过程复杂的正文撑持年夜多半通用服务对象(比方EJB和高低文干系对象)和JNDI对象的注进操纵。

  EJB3.0DI正文十分简便,易于利用。@Resource标签注进年夜多半通用服务对象和JNDI对象。上面的例子演示了怎样把JNDI中的服务器的默许DataSource对象注进POJO的一个字段变量中。DefaultDS是JNDI用于暗示DataSource的称号。在第一次利用myDb变量之前,会把准确的值主动地赋给它。

publicclassFooDao{

@Resource(name="DefaultDS")
DataSourcemyDb;

//利用myDb猎取数据库的JDBC毗连
}

  作为对字段变量间接注进的增补,我们还可使用EJB3.0中的@Resource正文,经由过程设置(setter)办法来注进对象。比方,上面的例子就注进了一个对话高低文干系(context)对象。使用程序一向没有显式挪用设置办法--该办法在被别的的任何办法挪用之前,会先被容器挪用。

@Resource
publicvoidsetSessionContext(SessionContextctx){
sessionCtx=ctx;
}

  关于加倍庞大的服务对象,已界说了一些公用的注进正文。比方,@EJB正文用于注进EJBstub,@PersistenceContext正文用于注进EntityManager对象(它为EJB3.0实体bean处置数据库会见)。上面的例子演示了怎样向一个有形态的对话bean注进EntityManager对象。@PersistenceContext正文的type属性指明被注进的EntityManager具有扩大的事件高低文干系--它不会主动地与JTA事件办理器一同提交,因而它能够用于那些在一个对话中超过多个线程的使用程序事件。

@Stateful
publicclassFooBeanimplementsFoo,Serializable{

@PersistenceContext(
type=PersistenceContextType.EXTENDED
)
protectedEntityManagerem;

publicFoogetFoo(Integerid){
return(Foo)em.find(Foo.class,id);
}
}

  EJB3.0标准界说了能够经由过程正文注进的服务器资本。可是它不撑持用户自界说的使用程序POJO的相互互相注进。

  在Spring中,你起首必要为POJO的服务对象界说一个设置办法(大概带参数的机关函数)。上面的例子显现POJO必要一个指向Hibernate对话工场的指针。

publicclassFooDao{

HibernateTemplatehibernateTemplate;

publicvoidsetHibernateTemplate(HibernateTemplateht){
hibernateTemplate=ht;
}

//利用Hibernate模板会见数据
publicFoogetFoo(Integerid){
return(Foo)hibernateTemplate.load(Foo.class,id);
}
}

  接上去,你能够指定容器怎样在运转时经由过程XML元素链猎取服务对象并把它绑缚到POJO上。上面的例子演示了把数据源绑缚到Hibernate对话工场,把对话绑缚到Hibernate模板对象,最初把模板对象绑缚到使用程序POJO的XML元素。这段Spring代码云云庞大的部分缘故原由在于我们必需手动地注进上层Hibernate管道对象,而EJB3.0EntityManager是由服务器主动地办理和设置的。可是这又让我们回到了Spring没有像EJB3.0那样与服务严密集成的会商中了。

<beanid="dataSource"
class="org.springframework
.jndi.JndiObjectFactoryBean">
<propertyname="jndiname">
<value>java:comp/env/jdbc/MyDataSource</value>
</property>
</bean>

<beanid="sessionFactory"
class="org.springframework.orm
.hibernate.LocalSessionFactoryBean">
<propertyname="dataSource">
<refbean="dataSource"/>
</property>
</bean>

<beanid="hibernateTemplate"
class="org.springframework.orm
.hibernate.HibernateTemplate">
<propertyname="sessionFactory">
<refbean="sessionFactory"/>
</property>
</bean>

<beanid="fooDao"class="FooDao">
<propertyname="hibernateTemplate">
<refbean="hibernateTemplate"/>
</property>
</bean>

<!--ThehibernateTemplatecanbeinjected
intomoreDAOobjects-->

  只管在Spring中基于XML的依附注进语法是庞大的,可是它却很壮大。你能够把任何POJO(包含你在使用程序中界说的)注进另外一个POJO。假如你真的但愿在EJB3.0使用程序中利用Spring的依附注进才能,你能够经由过程JNDI把Springbean工场注进EJB中。在某些EJB3.0使用程序服务器中,厂商大概界说了分外的非尺度的API,以注进恣意的POJO。个中一个很好的例子是JBossMicroContainer,它乃至比Spring更一般,由于它处置了面向方面编程(AOP)的依附性。

  结论

  只管Spring和EJB3.0的方针都是为松懈耦合的POJO供应企业级服务,可是它们是利用一模一样的办法来到达这个方针的。在这两个框架组件中都大批地利用了依附注进(DI)。

  利用EJB3.0的时分,基于尺度的办法、正文的大批利用、和与使用程序服务器的严密集成构成了壮大的厂商有关性和开辟者的高效力。利用Spring的时分,分歧地利用依附注进和会合的XML设置文件,同意开辟者机关加倍天真的使用程序,并在统一时候利用多个使用服务。

其实产生见解的过程就是训练自己发现问题,分析问题的能力。根据以上的认识我想谈下传统的学习与通过视频独立学习的优缺点:

灵魂腐蚀 发表于 2015-1-19 16:09:49

Java是一种计算机编程语言,拥有跨平台、面向对java

第二个灵魂 发表于 2015-1-24 13:26:55

一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。

分手快乐 发表于 2015-1-25 09:12:51

一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。

海妖 发表于 2015-2-2 18:05:12

你现在最缺的是实际的工作经验,而不是书本上那些凭空想出来的程序。

透明 发表于 2015-2-7 14:42:46

是一种使用者不需花费很多时间学习的语言

若天明 发表于 2015-2-8 19:52:31

Java自面世后就非常流行,发展迅速,对C++语言形成了有力冲击。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台

再现理想 发表于 2015-2-10 02:21:13

你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。

变相怪杰 发表于 2015-3-10 00:10:03

Java是一种计算机编程语言,拥有跨平台、面向对java

金色的骷髅 发表于 2015-3-17 03:10:34

有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)

莫相离 发表于 2015-3-17 03:10:35

Java 编程语言的风格十分接近C、C++语言。

若相依 发表于 2015-3-23 17:26:54

如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。
页: [1]
查看完整版本: JAVA网页编程之POJO使用架构:Spring与EJB 3.0的对照