プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle WebLogic Server Springアプリケーションの開発と管理
12c (12.2.1.1.0)
E79379-01
目次へ移動
目次

前

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

この章では、WebLogic ServerのJava EEベースのAvitek Medical Records (MedRec)サンプル・アプリケーションのSpringバージョンがあるMedRec-Springサンプル・アプリケーションについて説明します。

MedRec (Springバージョン)というサンプル・アプリケーションは、WebLogic Serverに含まれ、MedRec-Springと呼ばれます。次の項で説明するように、MedRec-Springでは、Java EEベースの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とともにそれらの設計と実装に関するドキュメントが含まれています。そのドキュメントは、ORACLE_HOME\wlserver\samples\server\docs\にあります(ここで、ORACLE_HOMEはWebLogic Serverをインストールしたディレクトリ)。WebLogic Serverコード・サンプルの詳細は、Oracle WebLogic Serverの理解のサンプル・アプリケーションおよびコード・サンプルを参照してください。

Springの制御の反転の構成

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

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

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

主に、依存関係インジェクションは@Autowiredアノテーションで構成されます。たとえば、ORACLE_HOME\wlserver\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サービス・クライアント・サービスの有効

ORACLE_HOME\wlserver\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の構成ファイルORACLE_HOME\wlserver\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)を使用します。構成は、ORACLE_HOME\wlserver\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構成を使用します。ORACLE_HOME\wlserver\samples\server\medrec-spring\modules\medrec\web\war\WEB-INF\applicationContext.xml内の構成を参照してください。

   <tx:jta-transaction-manager/>

   <tx:annotation-driven/>

すべてのトランザクションの境界設定がSpringの@Transactionalアノテーションによって実装されます。これは、EJB 3.0アプリケーションで行われる操作と同じです。ORACLE_HOME \wlserver\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) {
   }
}