亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

不需要應用服務器的J2EE

2019-11-18 12:43:57
字體:
來源:轉載
供稿:網友

  例子:消息驅動Bank

  為了闡述我們的觀點,我們將開發和安裝一個完整的樣板應用程序:一個消息驅動的銀行系統. 通過(幸虧有SPRing)改進的基于POJOs的編程模型和保留相同的事務,我們可以不需要EJB或者一個應用服務器來實現這個系統。在下一個部分,我們將從消息驅動架構產生到另一個架構.就像基于WEB的架構一樣.圖1展示我們的樣本應用程序的架構.  

不需要應用服務器的J2EE(圖一)


  Figure 1. Architecture of the message-driven bank

  在我們的例子中,我們將處理來自java消息服務隊列的銀行定單.一張定單的處理包括通過JDBC來更新當前帳戶的數據庫.為了避免信息的丟失和重復,我們將使用JTA和JTA/XA事務來配合更新:處理信息和更新數據庫將發生在一個原子事務里.資源部分可得到JTA/XA的更多信息.

  編寫應用程序代碼

  該應用程序將由兩個JAVA類組成: Bank(一個DAO)和MessageDrivenBank.如圖2.

不需要應用服務器的J2EE(圖二)


  Figure 2. Classes for the message-driven bank

  Bank是一個數據訪問對象,這個對象封裝數據庫訪問。MessageDrivenBank是一個消息驅動façade并且是DAO的委托.與典型的J2EE方法不同,這個應用程序不包括EJB類.

  第一步:編寫Bank DAO

  如下, Bank源代碼是很直接和簡單的JDBC操作.

package jdbc;
import javax.sql.*;
import java.sql.*;
public class Bank
{
  private DataSource dataSource;
  public Bank() {}
  public void setDataSource ( DataSource dataSource )
  {
    this.dataSource = dataSource;
  }

private DataSource getDataSource()
  {
    return this.dataSource;
  }

  private Connection getConnection()
  throws SQLException
  {
    Connection ret = null;
    if ( getDataSource() != null ) {
        ret = getDataSource().
              getConnection();
    }
    return ret;
  }

  private void closeConnection ( Connection c )
  throws SQLException
  {
    if ( c != null ) c.close();
  }
    
  public void checkTables()
  throws SQLException
  {
        
    Connection conn = null;
    try {
      conn = getConnection();
      Statement s = conn.createStatement();
      try {
        s.executeQuery (
        "select * from Accounts" );
      }
      catch ( SQLException ex ) {
        //table not there => create it
        s.executeUpdate (
        "create table Accounts ( " +
        "account VARCHAR ( 20 ), " +
        "owner VARCHAR(300), " +
        "balance DECIMAL (19,0) )" );
        for ( int i = 0; i < 100 ; i++ ){
          s.executeUpdate (
          "insert into Accounts values ( " +
          "'account"+i +"' , 'owner"+i +"', 10000 )"
          );
        }
      }
      s.close();
      }
      finally {
        closeConnection ( conn );

      }

      //That concludes setup
  }

    
  //
  //Business methods are below
  //

  public long getBalance ( int account )
  throws SQLException
  {
        
    long res = -1;
    Connection conn = null;

    try {
      conn = getConnection();
      Statement s = conn.createStatement();
      
      String query =
      "select balance from Accounts where account='"+
      "account" + account +"'";
      
      ResultSet rs = s.executeQuery ( query );
      if ( rs == null !rs.next() )
        throw new SQLException (
        "Account not found: " + account );
      res = rs.getLong ( 1 );
      s.close();
    }
    finally {
        closeConnection ( conn );
    }
    return res;
        
  }

  public void withdraw ( int account , int amount )
  throws Exception
  {
    Connection conn = null;

    try {
      conn = getConnection();
      Statement s = conn.createStatement();

      String sql =
      "update Accounts set balance = balance - "+
      amount + " where account ='account"+
      account+"'";
      
      s.executeUpdate ( sql );
      s.close();
    
    }
    finally {
        closeConnection ( conn );

    }
  }
}


  注重:代碼并沒有依靠EJB或任何專門的應用程序服務器.實際上,這是一個純JAVA代碼,這個JAVA代碼是能在任何J2SE環境下運行的.
你同時應注重:我們使用了來自JDBC的DataSource接口.這意味著我們的類是獨立于目前JDBC供給商提供的類. 你可能會迷惑,這怎么能與特定的數據治理系統(DBMS)提供商的JDBC實現緊密結合呢? 這里就是Spring框架幫你實現的. 這個技術被稱為依靠注入:在我們的應用程序的啟動期間,通過調用setDataSource方法,Spring為我們提供了相應的datasource對象.在后面幾部分我們會更多地提到Spring.假如我們在以前使用應用程序服務器,我們將不得不借助于JAVA命名綁定接口(JNDI)查詢.

  除了直接使用JDBC,我們也可以使用Hibernate或者一個JDO工具來實現我們的持久層.這同樣不需要任何的EJB代碼.

  第二步:配置BankDAO

  我們會將便用Spring框架來配置我們的應用程序.Spring不是必需的,但是使用Spring的好處是我們將可以簡單的添加服務,如:我們JAVA對象的事務和安全.這類似于應用服務器為EJB提供的東西,只是在我們的例子中Spring將變得更輕易.
Spring也答應我們把我們的類從目前的JDBC驅動實現中分離出來:Spring能夠配置Driver(基于我們的xml配置數據)并把它提供給BankDAO對象(依靠注入原理).這樣可以保持我們的JAVA代碼的清淅和集中.這步的Spring配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>


<beans>

<bean id="datasource"
class="com.atomikos.jdbc.nonxa.NonXADataSourceBean">

    <property name="user">
        <value>sa</value>
    </property>
    <property name="url">
        <value>jdbc:hsqldb:SpringNonXADB
        </value>
    </property>
    <property name="driverClassName">
        <value>org.hsqldb.jdbcDriver</value>
    </property>
    <property name="poolSize">
        <value>1</value>
    </property>
    <property name="connectionTimeout">
        <value>60</value>
    </property>
</bean>

<bean id="bank" class="jdbc.Bank">
        <property name="dataSource">
            <ref bean="datasource"/>
        </property>
</bean>

</beans>


  這個XML文件包括兩個對象的配置:訪問數據庫的DataSource和使用這個DataSource的Bank對象.下面是由Spring維護的一些基本任務.
  ·        創建應用程序(例: Bank和DataSource)需要的對象(“beans”).在XML文件中給出了這些對象的類名,并且在我們的例子中,這些對象需要有一個公共的無參數constrUCtor (Spring也答應參數,但是配置語法上有所不同).這些對象都被命名(XML中的id屬性),所以我們后面能夠引用這些對象. id也答應我們的應用程序找回它需要的已配置對象.
  ·        這些對象的初始化是通過在XML文件中的properties的值實現. 在XML文件中這些properties名 應與對應的類中的setXXX方法相對應.
  ·        將對象連接在一起 :一個property可能是另一個對象(例如:在我們例子中的數據源)的引用,引用可以通過id創建.

  注重:在我們下一步中, 我們將選擇配置一個JTA-enabled的數據源(由Atomikos Transactions提供,可用于企業和J2SE的JTA產品,我們將應用于我們的應用程序). 簡單起見,我們將使用HypersonicSQLDB,這個DBMS不需要專門的安裝步驟—它是在.jar文件里,就像JTA和Spring.

  但是,考慮到漸增的可靠性需求,強列推薦你使用XA-capable的DBMS和JDBC驅動.沒有XA的支持, 在crash或重啟之后你的應用程序將不能恢復原有數據. 資源部分有鏈接到關于事務和XA的信息和一些例子.

  作為一個練習,你可以試試從HypersonicSQLDB轉換到FirstSQL,一個易安裝XA-compliant的DBMS.換句話說,任何其他為企業預備的和XA-capable的DBMS也會做得很好.

  第三步:測試BankDAO

  讓我們來測試我們的代碼,(使用極限編程的程序員會首先寫測試,但因開始不是很清淅,所以我們直到現在才開始寫測試.)下面是一個簡單的單元測試.這個測試可在你的的應用程序里運行:它通過Spring獲得一個BANK對象來進行測試(這在setUp方法中實現).注重:這個測試使用清楚的事務劃分:每一個測試開始之前開始一個事務,每個測試結束時強制進行事務回滾.這是通過手工的方式來減少測試對數據庫數據的影響.

package jdbc;
import com.atomikos.icatch.jta.UserTransactionImp;
import junit.framework.TestCase;
import java.io.FileInputStream;
import java.io.InputStream;
import org.springframework.beans.factory.xml.XmlBeanFactory;

public class BankTest extends TestCase
{

    private UserTransactionImp utx;

    private Bank bank;

    public BankTest ( String name )
    {
        super ( name );
        utx = new UserTransactionImp();
        

    }

    protected void setUp()
        throws Exception
    {
        //start a new transaction
        //so we can rollback the
        //effects of each test
        //in teardown!
        utx.begin();
        
        //open bean XML file
        InputStream is =
            new FileInputStream("config.xml");

        //the factory is Spring's entry point
        //for retrieving the configured
        //objects from the XML file

        XmlBeanFactory factory =
            new XmlBeanFactory(is);

        bank = ( Bank ) factory.getBean ( "bank" );
        bank.checkTables();
    }

    protected void tearDown()
        throws Exception
    {
        //rollback all DBMS effects
        //of testing
        utx.rollback();
    }

    public void testBank()
    throws Exception
    {
        int accNo = 10;
        long initialBalance = bank.getBalance ( accNo );
        bank.withdraw ( accNo , 100 );
        long newBalance = bank.getBalance ( accNo );
        if ( ( initialBalance - newBalance ) != 100 )
            fail ( "Wrong balance after withdraw: " +
                   newBalance );
    }
    
}


  我們將需要JTA事務來確保JMS和JDBC都是原子操作.一般來說,當經常都是兩個或多個連接的時候,你應考慮一下JTA/XA。例如,在我們例子中的JMS和JDBC. Spring本身不提供JTA事務;它需要一個JTA實現或者委派一個應用服務器來處理這個事務.在這里,我們使用了一個JTA實現,這個實現可以在任何J2SE平臺上工作.
最終架構如下面圖3.白色方框代表我們的應用程序代碼.



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品国产一区二区三区| 亚洲欧美日韩另类| 4444欧美成人kkkk| 中文国产成人精品久久一| 在线成人一区二区| 日韩精品在线看| 91精品国产综合久久久久久蜜臀| 91在线观看免费高清完整版在线观看| 欧美成人精品在线| 亚洲午夜久久久影院| 精品丝袜一区二区三区| 欧美精品一区在线播放| 欧美日韩综合视频网址| 成人a在线观看| 97视频人免费观看| 欧美日韩精品中文字幕| 欧美黑人又粗大| 日韩电影中文字幕| 91精品在线影院| 亚洲一区中文字幕| 久久成人精品一区二区三区| 国产精品久久久久久久久久99| 国产精品女主播视频| 国产精品久久99久久| 国产精品69久久| 6080yy精品一区二区三区| 国产精品电影久久久久电影网| 国产精品女主播| 日韩黄在线观看| 亚洲美女在线视频| 精品久久久久久久久国产字幕| 久久激情视频久久| 欧美俄罗斯乱妇| 亚洲成色777777女色窝| 欧美日韩黄色大片| 日韩一区av在线| 欧美中文字幕在线观看| 久久久久久久久久久国产| 久久久久女教师免费一区| 欧美极品欧美精品欧美视频| 亚洲一区中文字幕在线观看| 色99之美女主播在线视频| 亚洲精品国产精品国自产观看浪潮| 亚洲国产婷婷香蕉久久久久久| 亚洲成人激情图| 久久艳片www.17c.com| 国产精品影片在线观看| 国产精品久久久久久久一区探花| 欧美在线一区二区视频| 日韩精品在线免费播放| 亚洲a一级视频| 色婷婷综合久久久久| 日韩精品免费综合视频在线播放| 亚洲男人第一网站| 亚洲欧美中文日韩在线v日本| www.日韩不卡电影av| 国产精品情侣自拍| 日韩精品中文字幕在线观看| 成人h猎奇视频网站| 最近更新的2019中文字幕| 2024亚洲男人天堂| 欧美日韩一区二区三区| 精品视频在线播放免| 亚洲日本成人网| 亚洲国产欧美日韩精品| 国产精品久久久久久久久影视| 国产精品成人免费电影| 国产亚洲视频在线| xvideos亚洲| 这里只有精品视频| 久久久久久久久久久久久久久久久久av| 亚洲国产中文字幕久久网| 亚洲精品乱码久久久久久金桔影视| 超碰97人人做人人爱少妇| 中文字幕国产亚洲2019| 亚洲精品一区二区三区婷婷月| 亚洲午夜精品久久久久久性色| 777777777亚洲妇女| 岛国av午夜精品| 在线精品国产成人综合| 国产欧美日韩中文字幕| 国产视频精品va久久久久久| 色噜噜狠狠狠综合曰曰曰88av| 在线播放国产一区二区三区| 欧美日韩国产综合视频在线观看中文| 亚洲国产精品一区二区三区| 亚洲国产精品成人av| 亚洲肉体裸体xxxx137| 91精品国产91久久久久久| 欧美另类高清videos| 成人夜晚看av| 精品国产一区二区三区在线观看| 欧美成人精品一区二区| 最近2019中文字幕mv免费看| 国产日韩av在线| 久久久久久噜噜噜久久久精品| 国产精品美女无圣光视频| 不卡伊人av在线播放| 91精品国产九九九久久久亚洲| 久久九九热免费视频| 国产精品成人一区二区三区吃奶| 亚洲高清免费观看高清完整版| 亚洲色图35p| 久久精品视频中文字幕| 亚洲一区二区三区成人在线视频精品| 亚洲最大成人在线| 亚洲国产精品久久久久秋霞蜜臀| 精品国产一区二区三区久久久| 黑人狂躁日本妞一区二区三区| 欧美在线一级va免费观看| 国产成人黄色av| 日韩中文av在线| 精品国产区一区二区三区在线观看| 国产99久久精品一区二区永久免费| 成人黄色在线播放| 亚洲综合在线中文字幕| 亚洲性猛交xxxxwww| 欧美中文在线观看| 97在线免费观看| 国产日韩在线观看av| 国产精品永久免费在线| 亚洲午夜激情免费视频| 久久激情视频久久| 日韩成人高清在线| 中文字幕国产亚洲2019| 91成人国产在线观看| xvideos国产精品| 久久亚洲精品国产亚洲老地址| 亚州av一区二区| 成人一区二区电影| 久久久久久com| 国产精品电影久久久久电影网| 成人久久久久爱| 国内自拍欧美激情| 亚洲美女www午夜| 日韩大陆欧美高清视频区| 一区二区三区日韩在线| 国产一区二区激情| 久久精品91久久香蕉加勒比| 亚洲一区中文字幕| 亚洲第一在线视频| 激情久久av一区av二区av三区| www.午夜精品| 美女av一区二区| 青草青草久热精品视频在线观看| 日韩精品极品在线观看| 久久成人免费视频| 亚洲免费小视频| 91久久精品国产| 欧洲s码亚洲m码精品一区| 欧美尺度大的性做爰视频| 亚洲国产古装精品网站| 亚洲男人7777| 成人性生交大片免费看视频直播| 欧美大胆在线视频| 日韩麻豆第一页| 日韩美女av在线| 亚洲一区久久久| 午夜欧美大片免费观看| 国产成人免费av| 久久五月天色综合| 久久久久久久成人| 国产69精品久久久久久| 久久视频在线免费观看|