posts - 310, comments - 6939, trackbacks - 0, articles - 3
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          Spring VS EJB 3 的若干認識誤區

          Posted on 2008-01-30 12:54 詩特林 閱讀(5837) 評論(8)  編輯  收藏 所屬分類: Spring
           應IT168寫的專稿:http://publish.itpub.net/j/2008-01-29/200801291007089.shtml
           

          Spring VS EJB 3 的若干認識誤區

           

          在開源領域,Spring開源框架已成為企業應用開發中使用最多的開源框架。Spring框架的優秀不但表現在其優雅的底層設計、使用方便快捷、面向工作實踐、超強粘合能力等方面,另外一個不可忽視的方面是Spring擁有一個世界一流且活躍的技術開發團隊。隨著Spring的流行,于是,大家開始對比Spring與另一種流行的框架組件EJB。目前網上關于SpringEJB的爭論頗多。很多架構師認為Spring會替代EJB,也有架構師認為Spring是開源的東西,是不成熟且無法和商業解決方案媲美的框架,因此,在SpringEJB的對比過程,有若干對Spring的片面認識。而本文希望通過對這些誤區的分析,給Spring一個原本的認識與理解。

          一、        前言

          EJB 3.0框架是JCP定義的并且被所有主流J2EE提供商支持的標準框架。EJB 3.0規范的發布版本目前已經有開源的和商業的實現,如JBOSSORACLEEJB 3.0大量使用了JAVA注解(Java annotations,是JDK1.5提供的新功能)。

          EJB最初的設計思想考慮的是為分布式的應用服務的,分布式是針對大型應用構造的跨平臺的協作計算,EJB最初的目的就是為這種計算服務的。但是軟件發展到目前為止,大多數應用不需要采用分布式的解決方案,因此用EJB顯得太臃腫了。Spring的出現恰恰為了解決這個問題。舉個例子來說,EJB就是導彈,專門設計為打高空飛機。但是現在發現飛機不多。于是將它用來對付步兵,這個實在太糟糕了。這個時候有人發明了狙擊步槍(Spring),發現對付步兵太好用了。

          Spring框架是一個廣受歡迎的但是非標準的開源框架。它主要由Interface21公司開發和控制。Spring框架的體系結構是基于注射依賴(DI)模式。Spring框架使用了大量的XML配置文件,它可以獨立應用,或者在現有的應用服務器上工作。

          這兩個框架有著一個共同的核心設計理念:它們的目標是為松耦合的POJO類提供中間件服務。框架通過在運行時截取執行環境,或將服務對象注射給POJO類的方式,將應用服務和POJO連接起來。POJO類本身并不關注如何連接,而且也很少依賴于框架。

          這樣,開發者可以將注意力集中在業務邏輯上,可以對他們的POJO類進行與框架無關的單元測試。并且,由于POJO類不需要繼承框架的類或實現框架提供的接口,開發者可以在更加靈活性的基礎上構建繼承體系,和搭建應用。

          盡管有著共同的理念,但這兩個框架采取了不同的方式來提供POJO服務。由于已經出了大量的比較SpringEJB3.0的文章。但發現,隨著Spring的發展,其中對Spring的認識難免有失偏頗的地方,因此,本文將考察它們之間幾個關鍵的認識上的誤區進行分析。

          二、        SpringXML VS EJB的注釋

          從應用開發者的角度來看,Spring的編程接口主要基于XML配置文件,而EJB 3.0則大量的使用了JAVA注解。XML文件可以表達復雜的關系,但是它們更加冗長而且不健壯。注解的方式很簡單明了,但是很難去表達復雜的或者繼承性的結構。

          由于EJB 3.0Spring相互學習了很多特性,所以,它們都在某種層次上支持XML和注釋。例如,EJB 3.0中可以應用XML配置文件作為一個選擇性的機制,用來改變注釋的默認行為。注釋也可以用來配置一些Spring服務。

          Spring 2中,采用了@PersistenceContext注釋的方式來整合JPAJava 持久性 API),從而實現了EntityManager對象的注入,同時通過@Transactional實現聲明式事務管理。Spring 2利用注釋來支持AspectJ(一種面向切面的框架,它擴展了Java語言),如@Aspect@Before@After@Around等等注釋。Spring 2中,使用@Repository注釋,可以直接操作JPAHibernate API,而不需要使用Spring模板。

          Spring的元數據模型非常的靈活的,因此在Spring中可以快速的建立起基于注釋的元數據模型。而從最近發布的Spring 2.5看來,事實上也是這樣。Spring 2.5全面支持JSR-250注釋(JSR-250技術規范主要涉及J2SEJ2EE平臺上開發普通語義概念的標注,提供一種獨立技術),如@Resource@PostConstruct@PreDestroy@WebServiceRef@EJB

          特別值得一提的是@Resource,最早是為了在EJB 3使用Spring的依賴注入功能。但如今其功能已經擴展了,不但支持像JNDI的查找,還可以注入任何的Spring管理對象。這就把Spring的優勢(Spring支持任何對象的依賴注入)和EJB的優勢(使用注釋代替XML)充分的結合起來了。

          Spring 2.5中提供了完整的基于注釋的依賴注入模型,如@Autowired@Qualifier注釋。用戶通過@Autowired注解來對Bean的屬性變量、屬性Setter方法以及構造函數進行標注,配合AutowiredAnnotationBeanPostProcessor完成對Bean的自動裝配。

          @Component注釋為用戶自定義原形進行了擴展。Spring可以自動的檢測到注釋的組件。例如下面的代碼

          <context:component-scan base-package="org.springframework.samples.petclinic.web" />

          Web控制器不需要額外的XML配置,因為使用了基于注釋的依賴注入以及基于注釋的請求映射。Web控制器通過如下的代碼進行管理:

          @Controller
          public class ClinicController {

             private final Clinic clinic;

             @Autowired
             public ClinicController(Clinic clinic) {
                this.clinic = clinic;
             }

          三、        EJB使用JPASpring使用Hibernate

          很多人都認為,在EJB 3中通過使用@PersistenceContext注釋提供的entityManager對象來獲得JPA的數據訪問,而在Spring中,通過對SessionFactory對象的注入獲得Hibernate數據訪問。從而自然而然地認中,EJB使用JPA來操作數據對象,而Spring使用Hibernate來操作數據對象。

          作為EJB3.0的一部分,JPA是一個好東西。其簡單的配置方式及強大的默認配置支持,使其可以輕松自由的存在于輕量與重量之間。事實上,Spring同樣支持使用JPA來操作數據對象(例如JpaTemplate),此外Spring提供了@PersistenceContext注釋來支持JPA。在輕量級 Spring 框架的第二代中添加了一大批特性,即使是新的服務器應用程序開發人員也能夠輕松上手。其關鍵增強之一就是 Spring 2 JPA的集成。@PersistenceContext注釋的使用示例如下面的代碼所示:

          package quickstart.service;

          import java.util.List;

          import javax.persistence.EntityManager;
          import javax.persistence.PersistenceContext;
          import javax.persistence.Query;

          import org.springframework.transaction.annotation.Transactional;

          import quickstart.model.Person;

          @Transactional
          public class PersonServiceImpl implements PersonService {
              private EntityManager em;

              @PersistenceContext
              public void setEntityManager(EntityManager em) {
                  this.em = em;
              }

              @SuppressWarnings("unchecked")
              public List<Person> findAll() {
                  Query query = getEntityManager().createQuery("select p FROM Person p");
                  return query.getResultList();
              }

              public void save(Person person) {
                  if (person.getId() == null) {
                      // new
                      em.persist(person);
                  } else {
                      // update
                      em.merge(person);
                  }
              }

              public void remove(int id) {
                  Person person = find(id);
                  if (person != null) {
                      em.remove(person);
                  }
              }

              private EntityManager getEntityManager() {
                  return em;
              }

              public Person find(int id) {
                  return em.find(Person.class
           id);
              }

          }

          @PersistenceContext會讓Spring在實例化的時候給服務注入一個EntityManager@PersistenceContext注解可以放在實例變量,或者setter方法前面。如果一個類被注解為@TransactionalSpring將會確保類的方法在運行在一個事務中。

          Spring JPA 應用程序在 Tomcat 上運行時,要讓 JPA 支持正常工作,需要在類裝入期間進行字節碼連接。來自 Tomcat 的標準類裝入器不支持這個,需要用特定于 Spring 的類裝入器實現這個功能。要把這個特定于 Spring 的類裝入器安裝到 Tomcat 服務器,首先要把 spring-tomcat-weaver.jar 拷貝到 Tomcat server/lib 子目錄。這個目錄包含的庫屬于 Tomcat 服務器私有,可以在 Spring 2 下載的 dist/weaver 目錄下找到 spring-tomcat-weaver.jar 庫。

          四、        提供商無關性

          開發者選擇JAVA平臺的一個最重要的原因就是它的提供廠商無關性。EJB 3.0是一個被設計為對提供商沒有依賴性的開放的標準。EJB 3.0規范由企業JAVA社區的主流開源組織和廠商共同編寫和支持的。EJB 3.0框架使開發者的應用程序實現可以獨立于應用服務器。

          比如,JBossEJB 3.0的實現是基于Hibernate的,OracleEJB 3.0實現是基于TopLink的,但是,在JBoss或者Oracle上跑應用程序,開發者既不需要去學習Hibernate,也不需要學習TopLink提供的獨特API。廠商無關性使EJB 3.0框架區別于當前其他任何的POJO中間件框架。

          很多人認為,盡管在任何應用服務器都上可以使用Spring框架,但基于Spring的應用仍然被限制于Spring本身,以及在應用中使用到的Spring提供的各種特別服務。但事實上是不是如此呢?大家應該知道,Spring的應用程序中,JtaTransactionManager使用了自動檢測機制,不管是MBeans應用服務器還是Tomcat應用服務器。同理,當使用JPA時,Spring自動檢測persistence.xml文件,并且創建EntityManagerFactory對象。在上面這些機制中,Spring不管是采用注釋(如PersistenceContext@Transactional@Resource等等)還是采用XML(如”jee:indi-lookup”等等),都可以像EJB應用一樣的與應用服務器提供商無關。

          五、        小結

          筆者認為,EJBSpring設計的角度根本不同,就目前來看,還不能說哪一個能完全打倒另外一個。首先EJB最初的設計思想考慮的是為分布式的應用服務的。就因為這個原因,使得開發一個EJB不難,但是開發一個好的EJB卻非常難。此外對于中小型的應用項目而言,基本不采用分布式的解決方案,那么為什么要采取一個為分布式設計的方案來解決非分布式的問題呢? Spring就是為了解決這個問題而誕生的。

          本文中,筆者希望比較客戶的評價Spring相對EJB所具有的一些特性,同時,Spring可以與EJB進行協同的工作,Spring可以應用到EJB應用中去,同樣,EJB可以在Spring應用中很好的使用。同時,Spring如今有力的支持注釋:@Resource@PersistenceContext@PostConstruct@PreDestroy@EJB@WebServiceRef。當然,Spring 中不只是能使用Hibernate這樣的ORM框架,同樣可以使用JPA。更妙的是,Spring越來越與應用服務器提供商無關了,很容易實現在不同的應用服務中進行移植。



          評論

          # re: Spring VS EJB 3 的若干認識誤區  回復  更多評論   

          2008-01-30 13:32 by loocky
          文不對題

          # re: Spring VS EJB 3 的若干認識誤區  回復  更多評論   

          2008-01-30 16:57 by 地球玩家
          JPA還不一樣要具體的ORM框架支撐,如Hibernate

          # re: Spring VS EJB 3 的若干認識誤區  回復  更多評論   

          2008-02-17 12:55 by 93ttx
          不錯呀。好文章……

          # re: Spring VS EJB 3 的若干認識誤區  回復  更多評論   

          2008-04-28 16:59 by BeanSoft
          截至到現在,Spring集團正式投入EJB的懷抱了,嘿嘿。。。沒辦法呢,最后都要背靠Java EE掙大錢。

          # re: Spring VS EJB 3 的若干認識誤區[未登錄]  回復  更多評論   

          2008-06-19 17:16 by 萬里
          哇噻 講的太好了........

          # re: Spring VS EJB 3 的若干認識誤區[未登錄]  回復  更多評論   

          2008-06-19 17:17 by 萬里
          ^_^

          呵呵 好文章.........

          # re: Spring VS EJB 3 的若干認識誤區[未登錄]  回復  更多評論   

          2009-04-13 21:08 by anna
          學習了

          # re: Spring VS EJB 3 的若干認識誤區  回復  更多評論   

          2009-04-26 00:37 by springvsejb
          very good!

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 大安市| 隆尧县| 贵州省| 项城市| 文水县| 澄迈县| 武威市| 蒙城县| 天祝| 建湖县| 宁阳县| 游戏| 九江县| 淮南市| 恩平市| 利津县| 舒城县| 芜湖县| 阳曲县| 定州市| 丰都县| 延边| 克什克腾旗| 抚宁县| 清新县| 昌邑市| 花垣县| 株洲市| 万载县| 永仁县| 青冈县| 威信县| 屯留县| 枞阳县| 驻马店市| 安顺市| 镇沅| 酉阳| 长阳| 石泉县| 凤城市|