ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebLogic ServerでのSpringのサポート
11g リリース1(10.3.3)
B61651-01
  目次へ移動
目次

前
 
 

7 SpringベースのOracle Weblogic Serverアプリケーションの開発

MedRec (Springバージョン)というサンプル・アプリケーションは、WebLogic Serverに含まれ、MedRec-Springと呼ばれます。サンプル・アプリケーションは、WebLogic Server J2EEベースのAvitek Medical Recordsサンプル・アプリケーション(MedRec)に基づきます。以下の項で説明するように、MedRec-Springでは、J2EEベースのMedrecコンポーネントはSpringコンポーネントに置き換えられます。

  1. Springの制御の反転の構成

  2. SpringのWebサービス・クライアント・サービスの有効化。Springでは、Webサービスのプロキシを生成するJAX-WCファクトリが提供されます。

  3. JMSサービスを実行時にアプリケーションで利用できるようにする

  4. JPAデータ・アクセスの使用

  5. トランザクション管理のためにSpringトランザクション抽象化レイヤーの使用

以降の項に示すサンプル・コードはMedRec-Springからのコードです。


注意:

WebLogic Serverをインストールするときには、MedRec-Springはデフォルトでインストールされません。カスタムインストールを選択して、「製品およびコンポーネントの選択」ページから「サーバー・サンプル」を選択します。

すでに、WebLogic Serverがインストールされている場合、インストーラを再起動して、WebLogic ServerがインストールされているMiddlewareホームを選択し、カスタム・インストールを選択して、「製品およびコンポーネントの選択」ページから「サーバー・サンプル」を選択します。

Medrec-Springとともにそれらの設計と実装に関するドキュメントが含まれています。そのドキュメントは、WL_HOME\samples\server\docs\にあります。次のように、Windowsの「スタート」メニューからそれを表示することができます: 「スタート」>「プログラム」>「Oracle WebLogic」>「WebLogic Server」>「サンプル」>「ドキュメント」


Springの制御の反転の構成

Springでは、他のbeanへの参照(注入されるプロパティ)は、Springの構成ファイルapplicationContext-web.xmlで構成されます。

Spring 2.5アノテーション駆動型構成がMedRec-Springで使用されます。アプリケーション・コンテキストは、Springによって@ServiceのようなSpring固有のアノテーションを検出するSpring beanが自動的にスキャンされるように構成されているので、個々のSpring beanをXML構成ファイルで宣言する必要はありません。WL_HOME\samples\server\medrec-spring\modules\medrec\web\war\WEB-INF\applicationContext.xml内の構成は、以下のとおりです。

<context:component-scan base-package="com.oracle.medrec"/>

主に、依存性インジェクションは@Autowiredアノテーションで構成されます。たとえば、WL_HOME\samples\server\medrec-spring\modules\medrec\domain\src\com\oracle\medrec\service\impl\RecordServiceImpl.javaの内容は以下のとおりです。

@Service("recordService")
@Transactional
public class RecordServiceImpl implements RecordService {

    @Autowired
    private RecordRepository recordRepository;

    @Autowired
    private PatientRepository patientRepository;

    @Autowired
    private PhysicianRepository physicianRepository;

これらのアノテーションは、EJB 3.0の開発と同様な開発を提供します。詳細は、http://www.springsource.org/documentation/にあるSpringの関連ドキュメントの「Annotation Type Autowired」を参照してください。

SpringのWebサービス・クライアント・サービスの有効

WL_HOME\samples\server\medrec-spring\modules\physician\web\war\WEB-INF\applicationContext.xmlからの次の例に示すように、MedRec-Springは、Web Servicesの動的プロキシを公開するためにSpring JaxWsPortProxyFactoryBeanを使用します。

<bean id="patientService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
   <property name="serviceInterface" value="com.oracle.physician.service.PatientService"/>
   <property name="wsdlDocumentUrl" 
         value="http://localhost:7011/medrec/webservices/PatientFacadeService?WSDL"/>
   <property name="namespaceUri" value="http://www.oracle.com/medrec"/>
   <property name="serviceName" value="PatientFacadeService"/>
   <property name="portName" value="PatientFacadePort"/>
</bean>

<bean id="physicianService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
   <property name="serviceInterface" value="com.oracle.physician.service.PhysicianService"/>
   <property name="wsdlDocumentUrl"
         value="http://localhost:7011/medrec/webservices/PhysicianFacadeService?WSDL"/>
  <property name="namespaceUri" value="http://www.oracle.com/medrec"/>
  <property name="serviceName" value="PhysicianFacadeService"/>
  <property name="portName" value="PhysicianFacadePort"/>
</bean>

<bean id="recordService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
  <property name="serviceInterface" value="com.oracle.physician.service.RecordService"/>
  <property name="wsdlDocumentUrl"
         value="http://localhost:7011/medrec/webservices/RecordFacadeService?WSDL"/>
  <property name="namespaceUri" value="http://www.oracle.com/medrec"/>
  <property name="serviceName" value="RecordFacadeService"/>
  <property name="portName" value="RecordFacadePort"/>
</bean>

この方法により、ツールで生成されたWebサービスのスタブを使用する必要はありません。詳細は、Springの関連ドキュメント(http://www.springsource.org/documentation/)の「JaxWsPortProxyFactoryBean」を参照してください。

JMSサービスを実行時にアプリケーションで利用できるようにする

Springでは、JMSサービスが実行時にアプリケーションに提供されるように構成する必要があります。MedRec-Springでは、OracleはSpringの構成ファイルWL_HOME\samples\server\medrec-spring\modules\medrec\web\war\WEB-INF\applicationContext.xmlに次のコードを実装することによって、実行時にJMSサービスがアプリケーションに利用できるようにします。

<!--- Messaging ************************************* -->
   <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
      <property name="connectionFactory" ref="connectionFactory"/>
   </bean>
   <jee:jndi-lookup id="connectionFactory" jndi-name="weblogic.jms.XAConnectionFactory"/>
        
   <jee:jndi-lookup id="patientNotificationQueue"
      jndi-name="com.oracle.medrec.jms.PatientNotificationQueue"/>
   <bean id="messageListener" 
   class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
      <property name="delegate" ref="patientNotifierBroker"/>
      <property name="defaultListenerMethod" value="notifyPatient"/>
   </bean>

   <bean id="messageListenerContainer"
         class="org.springframework.jms.listener.DefaultMessageListenerContainer">
      <!--<property name="taskExecutor" ref="taskExecutor"/>-->
      <property name="connectionFactory" ref="connectionFactory"/>
      <property name="messageListener" ref="messageListener"/>
      <property name="destination" ref="patientNotificationQueue"/>
      <!-- no need to use XA transaction now -->
      <property name="sessionTransacted" value="true"/>
</bean>

ここで、Springフレームワークからの様々なBeanが宣言されます。特に、jmsTemplateは、基底のJMS APIをラップして、メッセージを送信するために使用します。messageListenerContainerは、メッセージドリブンBeanコンテナと同じ機能を提供し、MedRec-SpringのJMSリスナーが登録されます。

JPAデータ・アクセスの使用

MedRec-Springは、データ・ソースを管理するには、標準Java Persistence API (JPA)を使用します。構成はWL_HOME\samples\server\medrec-spring\modules\medrec\domain\src\META-INF\persistence.xmlにあります。

    <persistence-unit name="MedRec" transaction-type="JTA">
        <jta-data-source>jdbc/MedRecGlobalDataSourceXA</jta-data-source>
        <class>com.oracle.medrec.model.Address</class>
        <class>com.oracle.medrec.model.Administrator</class>
        <class>com.oracle.medrec.model.BaseEntity</class>
        <class>com.oracle.medrec.model.PersonName</class>
        <class>com.oracle.medrec.model.Patient</class>
        <class>com.oracle.medrec.model.Physician</class>
        <class>com.oracle.medrec.model.Prescription</class>
        <class>com.oracle.medrec.model.Record</class>
        <class>com.oracle.medrec.model.RegularUser</class>
        <class>com.oracle.medrec.model.User</class>
        <class>com.oracle.medrec.model.VersionedEntity</class>
        <class>com.oracle.medrec.model.VitalSigns</class>
        <properties>
            <property name="kodo.jdbc.SynchronizeMappings"
                      value="buildSchema"/>
        </properties>
    </persistence-unit>

MedRec-Springはアノテーション駆動型アプローチ(この場合、すべてのDAOのための@Repository)を使用しているため、MedRec-SpringはSpring構成ファイルにData Access Object (DAO)を宣言しません。よって、これらのすべてが自動的にSpringによって管理されます。たとえば、RecordRepositoryImpl.javaを参照してください。

@Repository
public class RecordRepositoryImpl
         extends EntityRepositorySupport<Record, Long> implements RecordRepository {

      public List<Record> findRecordsByPatientId(Long patientId) {
         return findByProperty("Record.findRecordsByPatientId", patientId);
      }
}

トランザクション管理のためにSpringトランザクション抽象化レイヤーの使用

MedRec-Springは、WebLogic JTAトランザクション・マネージャを使用およびアノテーション・ベース宣言型トランザクションの管理を有効するためにSpring 2.5構成を使用します。「WL_HOME\samples\server\medrec-spring\modules\medrec\web\war\WEB-INF\applicationContext.xml」内の構成を参照してください。

   <tx:jta-transaction-manager/>

   <tx:annotation-driven/>

すべてのトランザクションの境界設定がSpringの@Transactionalアノテーションによって実装されます。これは、EJB 3.0アプリケーションで行われる操作と同じです。「WL_HOME\samples\server\medrec-spring\modules\medrec\domain\src\com\oracle\medrec\service\impl\RecordServiceImpl.java」を参照してください。

@Service("recordService")
@Transactional
public class RecordServiceImpl implements RecordService {

…
   public void createRecord(Record record, Long physicianId, Long patientId) {

   }

   @Transactional(readOnly = true)
   public List<Record> getRecordsByPatientId(Long patientId) {
      }

   @Transactional(readOnly = true)
   public Record getRecord(Long id) {
   }
}