ヘッダーをスキップ

Oracle Containers for J2EE サーブレット開発者ガイド
10g(10.1.3.1.0)

B31859-01
目次
目次
索引
索引

戻る 次へ

7 サービスおよびリソース参照の注釈の使用

OC4Jは、サーブレット2.5仕様に記載される注釈をサポートし、コンポーネント・インスタンスがアプリケーションで使用可能になる前に、リソース参照を挿入します。 次の項では、OC4Jでの注釈の使用方法について説明します。

注釈機能の概要

J2SE 5.0以上では、外部リソースの構成データおよび依存性を、Javaコードで注釈と呼ばれるメタデータとして指定できます。 そのようなデータは、構成ファイル内に定義するか、EJBやWebサービスなどのサービスまたはデータソースやJMS宛先などのリソース参照の注釈内に定義することができます。

たとえば、J2EE 1.4では、サーブレットがEJBを参照する前に、開発者は次のようなejb-local-ref要素を定義する必要があります。

<ejb-local-ref>
 <ejb-ref-name>ejb/HelloWorld</ejb-ref-name>
 <local>oracle.ejb.HelloWorld</local>
</ejb-local-ref>

次に、コード内のEJBを参照するために、開発者は次のコードの一部分としてJNDIを使用する必要があります。

Context ic = new InitialContext();

HelloWorld helloWorld = (HelloWorld)ic.lookup("java:comp/env/ejb/HelloWorld");
helloWorld.greet("Hello!");

サーブレット2.5では、クライアント・コードは単純化され、OC4Jは正確なリソースまたはサービスを挿入します。 クライアントは、リソースまたはサービスを、次のような注釈に指定する以外、何も必要ありません。

@EJB
private HelloWorld helloWorld;
helloWorld.greet("Hello!");

注釈および挿入

Webアプリケーションのデプロイメント・ディスクリプタ内のweb-app要素のmetadata-complete属性で、Webディスクリプタおよびその他のこのモジュールの関連デプロイメント・ディスクリプタ(たとえばWebサービス・ディスクリプタ)が完了しているかどうかを指定します。 web.xmlファイルでversion="2.5"を設定してサーブレット2.5が使用されるか、サーブレット2.5スキーマ・ネームスペースが指し示される場合、OC4Jサーブレット・コンテナはmetadata-completeフラグを確認して、注釈を処理するかどうか判断します。 version2.4以前のバージョンに設定されている場合、サーブレット・コンテナはいずれの注釈も処理しません。

metadata-completeがサーブレット2.4のデフォルト値であるtrueに設定されている場合、サーブレット・コンテナはアプリケーションのクラス・ファイル内にあるすべてのサーブレット注釈を無視します。 metadata-complete属性がない、またはサーブレット2.5のデフォルト値であるfalseに設定されており、version2.5に設定されている場合、サーブレット・コンテナはサーブレット注釈のアプリケーションのクラス・ファイルを検証し、次のように注釈をサポートします。

  1. OC4Jサーブレット・コンテナは、WEB-INF/ディレクトリ内またはWEB-INF/lib/ディレクトリの下のJARファイルにあるWebアプリケーションのクラスに対する注釈参照のためにリソースまたはサービス参照を検査します。

    また、サーブレット・コンテナは、MANIFEST.MF内にリストされるJARファイルへの注釈サポートも提供します。

  2. OC4Jサーブレット・コンテナは、Webアプリケーション・デプロイメント・ディスクリプタ内で宣言され、次のインタフェースを実装する管理されたコンポーネント・クラスに対する注釈サポートを提供します。

    • javax.servlet.Servlet

    • javax.servlet.Filter

    • javax.servlet.ServletContextListener

    • javax.servlet.ServletContextAttributeListener

    • javax.servlet.ServletRequestListener

    • javax.servlet.ServletRequestAttributeListener

    • javax.servlet.http.HttpSessionListener

    • javax.servlet.http.HttpSessionAttributeListener

  3. OC4Jサーブレット・コンテナは、すべてのライフサイクル・メソッドがインスタンスでコールされる前にリソースまたはサービス参照を挿入します。

    • javax.servlet.Servletおよびjavax.servlet.Filterに対するinit()

    • javax.servlet.ServletContextListenerに対するcontextInitialized()

    • javax.servlet.ServletRequestListenerに対するrequestInitialized()

  4. 注釈およびデプロイメント・ディスクリプタ・エントリの両方によって環境エントリが宣言されている場合、デプロイメント・ディスクリプタ・エントリの情報でResourceEJBまたはWebServiceRef注釈内の情報の一部をオーバーライドできます。

    次の仕様では、デプロイメント・ディスクリプタ・エントリを使用して注釈情報をオーバーライドする場合のルールが説明されています。

    • Resource注釈をオーバーライドするルールは、Java EE 5仕様を参照してください。

    • EJB注釈をオーバーライドするルールは、EJB仕様を参照してください。

    • WebServiceRef注釈をオーバーライドするルールは、WebServiceRef仕様を参照してください。

  5. OC4Jサーブレット・コンテナで、クラス用に挿入する必要があるリソースまたはサービスが見つからない場合は、クラスの初期化が失敗し、OC4Jは次の警告メッセージを発行します。

    Some resource(s) and/or service(s) to be injected cannot be found for class name. 
    class name will not be put to service.
    
  6. すべてのリソースまたはサービス参照が挿入された後、いずれのライフサイクル・メソッドがインスタンスでコールされる前に、PostConstruct注釈でマークされたメソッド(ある場合)を起動して、挿入したリソースを初期化する機会をサーブレットに与える必要があります。 「PostConstruct注釈」を参照してください。

  7. サーブレットをサービスから取り出す前に、PreDestroy注釈でマークされたメソッド(ある場合)を起動して、挿入したリソースを解放する機会をサーブレットに与える必要があります。 「PreDestroy注釈」を参照してください。

OC4Jの注釈

この項では、OC4Jがサポートする注釈を説明します。

EJB注釈

Resource注釈

Resources注釈

PostConstruct注釈

PreDestroy注釈

PersistenceUnit(s)注釈

PersistenceContext(s)注釈

WebServiceRef注釈

DeclaresRoles注釈

RunAs注釈

EJB注釈

アプリケーション・コンポーネントのフィールドまたはメソッドのEJB注釈は、デプロイメント・ディスクリプタのejb-refまたはejb-local-ref要素と同等です。 フィールドにEJB注釈がある場合、OC4Jはフィールドに対応するEJBコンポーネントへの参照を挿入します。

EJB注釈では、Beanのローカルまたはリモート・ホーム・インタフェースまたはEJB 3 Beanのビジネス・インタフェースを参照できます。 EJB 3のビジネス・インタフェースを参照する場合、OC4JはEnterprise Beanのインスタンスへの参照を挿入します。

短いEJB注釈の例を次に示します。

   @EJB private ShoppingCart myCart;

すべての注釈フィールドを使用する長いEJB注釈の例を次に示します。

   @EJB(
      name = "ejb/shopping-cart",
      beanName = "Cart1",
      beanInterface = ShoppingCart.class,
      description = "Items for purchase"
   )
   private ShoppingCart myCart;

EJB注釈の詳細は、EJB仕様を参照してください。

「注釈の例」に示す例には、EJB注釈が含まれています。

Resource注釈

Resource注釈を使用して、データソースやJMS宛先、環境エントリなどのリソースに対する参照を宣言します。 この注釈を使用する場合、デプロイメント・ディスクリプタ内の<resource-ref><message-destination-ref><env-ref>、または<resource-env-ref>要素で参照を宣言する必要はありません。

Resource注釈をフィールドまたはsetterメソッドに適用する場合、OC4Jは注釈で宣言されたリソースに対する参照を挿入し、リソースのJNDI名に参照をマッピングします。 注釈をクラスに適用する場合、注釈はアプリケーションが実行時に参照するリソースを宣言します。

挿入はそれぞれJNDIルックアップに対応します。 注釈でJNDI名を明示的に指定しない場合、クラスの完全修飾名と結合したフィールド名をJNDI名として使用します。 たとえば、パッケージcom.example内のクラスMyAppmyDbという名のフィールドのデフォルトJNDI名は、java:comp/env/com.example.MyApp/myDbです。 すべてのJNDI名は、java:comp/env/に対して相対的です。 注釈をsetterメソッドに適用する場合、クラス名で修飾されるメソッドに対応するJavaBeanプロパティ名がデフォルトです。 注釈をクラスに適用する場合、デフォルトは存在しないため、名前を指定する必要があります。

次の例では、JNDI名が指定されていないため、OC4JはデフォルトのJNDI名を使用します。

   @Resource
   private DataSource myDB;

次の例では、JNDI名が明示的に指定されています。

   @Resource(name="customerDB")
   private DataSource myDB;

注釈に関する一般情報は、Java EE 5仕様を参照してください。

「注釈の例」に示す例には、Resources注釈が含まれています。

Resources注釈

注釈の繰返しは認められていないため、Resources注釈は次の形式で複数のResource注釈のコンテナとして機能します。

  public @interface Resources {
      Resource[] value;
  }
  // value - Array of multiple resources.

次の例では、データソースおよびコネクション・ファクトリのために2つのResource注釈をクラスに含むResources注釈を示します。

   @Resources ({
      @Resource (name = "myDB", type=javax.sql.DataSource),
      @Resource (name = "myCF", type=javax.jms.ConnectionFactory)
   )
   public class MulResClass {
      //...
   }

PostConstruct注釈

すべてのその他のリソース挿入が完了した後、いずれかのライフサイクル・メソッドがインスタンスでコールされる前に、OC4JはメソッドをPostConstruct注釈を使用して起動します。 これにより、コンポーネントは作成後の処理が可能になります。 クラスに他の注釈がない場合でも、OC4Jはこのメソッドを起動します。

PostConstruct注釈の例を次に示します。

   @PostConstruct
   void doPostInjectionProcessing {
      //...


注意

PostConstruct注釈により、サーブレットの任意のメソッドがinit()メソッドとして機能します。 


PreDestroy注釈

OC4Jは、サーブレットをサービスから取り出す前に、PreDestroy注釈を使用してメソッドを起動します。 これにより、サーブレットは挿入されたリソースを解放します。 クラスに他の注釈がない場合でも、OC4Jはこのメソッドを起動します。

PreDestroy注釈の例を次に示します。

   @PreDestroy
   void doPreDestroyProcessing {
      //...
      }


注意

PreDestroy注釈により、サーブレットの任意のメソッドがdestroy()メソッドとして機能します。 


PersistenceUnit(s)注釈

PersistenceUnit注釈は、EJB 3.0永続性を使用する際に必要です。 永続性ユニットは、関連するエンティティBeanのセットを管理するエンティティ・マネージャ(永続性コンテキスト)に関する構成の詳細を持ちます。 永続性コンテキストに対する注釈は、「PersistenceContext(s)注釈」を参照してください。

サーブレットのフィールドまたはメソッドに、PersistenceUnit注釈を使用して注釈を付けられます。 論理永続性ユニット参照は、永続性ユニットのエンティティ・マネージャ・ファクトリを参照します。

単一の永続性ユニットを宣言する例を次に示します。

   @PersistenceUnit
   EntityManagerFactory emf;

サーブレットで複数の永続性ユニットを宣言する場合、次のように、各ユニットに明示的unitNameを指定する必要があります。

   @PersistenceUnit(unitName="InventoryManagement")
      EntityManagerFactory emf;

PersistenceUnit注釈は、persistence.xml内のpersistence-unit-ref要素と同じです。

永続性ユニット参照の詳細は、Java EE 5仕様を参照してください。

PersistenceContext(s)注釈

PersistenceContext注釈は、EJB 3.0永続性を使用する際に必要です。 永続性コンテキストは、一連の関連するエンティティBeanを管理するエンティティ・マネージャです。 永続性ユニットは、永続性コンテキストに関する構成の詳細を持ちます。 永続性ユニットに対する注釈の詳細は、「PersistenceUnit(s)注釈」を参照してください。 PersistenceContext注釈の例を次に示します。

   @PersistenceContext
   EntityManager em;

サーブレットで複数の永続性ユニットを宣言する場合、次のようにunitName属性で明示的なユニット名を指定する必要があります。

   @PersistenceContext(unitName="InventoryManagement")
   EntityManager em;

この注釈は、persistence.xml内のpersistence-context-ref要素と同じです。

永続性コンテキスト参照の詳細は、Java EE 5仕様を参照してください。

WebServiceRef注釈

WebServiceRef注釈を使用した注釈付けは、Webサービスへの参照を提供するデプロイメント・ディスクリプタ内の<resource-ref>の宣言と同じです。

この注釈には、2つの主な用途があります。

WebServiceRef注釈の例を次に示します。

   // Generated Service Interface
   @WebServiceRef
   private StockQuoteService stockQuoteService;

   // SEI
   @WebServiceRef(StockQuoteService.class)
   private StockQuoteProvider stockQuoteProvider;

WebServiceRef注釈の詳細は、Java API for XML-Based Web Services 2.0(JSR 224)を参照してください。

DeclaresRoles注釈

DeclaresRoles注釈は、アプリケーションのセキュリティ・モデルを構成するすべてのセキュリティ・ロールを定義します。 この注釈をクラスで指定し、注釈を付けたクラスのメソッド内からテスト可能なロールをisCallerInRoleをコールして定義することができます。

DeclaresRoles注釈の例を次に示します。

   @DeclaresRoles("Manager")
   public class CorporationServlet {
      //...
   }

この注釈は、web.xmlファイルの次のコードと同じです。

   <web-app>
      <security-role>
         <role-name>Manager</role-name>
      </security-role>
   </web-app>

DeclaresRoles注釈の詳細は、Common Annotations for the JavaTM Platform(JSR250)を参照してください。

RunAs注釈

RunAs注釈は、デプロイメント・ディスクリプタの<run-as>要素と同じです。 この注釈は、javax.servlet.Servletインタフェースを実装するクラスまたはそのサブクラスでのみ使用できます。

RunAs注釈の例を次に示します。

   @RunAs("Admin")
   public class CorporationServlet {
      //...
   }

この注釈は、web.xmlファイルの次のコードと同じです。

   <servlet>
      <servlet-name>CorporationServlet</servlet-name>
      <run-as>Admin</run-as>
   </servlet>

RunAs注釈の詳細は、Common Annotations for the JavaTM Platform(JSR250)を参照してください。

注釈ルールとガイドライン

注釈を使用する場合のルールをいくつか説明します。 一般的な注釈のガイドラインの詳細は、Java EE 5仕様を参照してください。

サーブレットのバージョン2.5のパフォーマンスへの注釈の影響

注釈を、サーブレットのバージョン2.5でWebアプリケーションに使用するかどうかにかかわらず、<web-app>metadata-complete属性がデプロイメント・ディスクリプタにない場合またはfalseに設定されている場合(サーブレット2.5のデフォルト値)、OC4JはWEB-INF/およびWEB-INF/libの下のすべてのクラスをロードして、注釈を検索する必要があります。 ロードを行うと、起動時にOracle Application Serverのパフォーマンスに影響する場合があります。 注釈を使用しない場合、metadata-complete="true"を指定することでパフォーマンスへの影響を回避できます。

起動時のパフォーマンスに影響を与えるのは、サーブレットのバージョン2.5を使用するWebアプリケーションのみです。 サーブレットのバージョン2.4以下を使用するWebアプリケーションでは、パフォーマンスに影響はありません。

注釈の例

この項では、注釈および対応するweb.xmlファイルを使用したサーブレットの例を示します。

サーブレットはサーブレット2.5の方法を示し、コメントアウトされた部分は比較のためのサーブレット2.4の方法です。 サーブレットは、1つの@EJB注釈および2つの@Resource注釈を示します。

web.xmlファイルは、注釈を使用できるようにするために必要なversion=およびmetadata-complete設定を説明します。

<web-app version="2.5" metadata-complete="false">
 ...
</web-app>

詳細は、次のサイトのドキュメント『How-To: Using Dependency Injection In Web Module』を参照してください。

http://www.oracle.com/technology/tech/java/oc4j/10131/how_to/index.html

次に、web.xmlファイルの例を示します。
<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.5"
        metadata-complete="false"
>

    <display-name>Annotation Example</display-name>
<description>A few examples of Servlet 2.5 Annotation and Resource 
Injection</description>

    <servlet>
        <display-name>hello</display-name>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>HelloServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

  <env-entry>
    <env-entry-name>EmpNo</env-entry-name>
    <env-entry-type>java.lang.Integer</env-entry-type>
    <env-entry-value>15</env-entry-value>
  </env-entry>
</web-app>
次に、HelloServlet.javaサーブレットの例を示します。
import java.io.*;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.annotation.Resource;
import javax.sql.*;
import java.sql.*;
import javax.naming.*;
import org.acme.*; 
import javax.rmi.*;
import javax.ejb.*;
public class HelloServlet extends HttpServlet {

    @EJB HelloObject bean;
    @Resource(name="EmpNo") int empNo;
    @Resource(name="jdbc/OracleDS") private DataSource db;

    public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        res.setContentType("text/html");

        PrintWriter writer = res.getWriter();

        // ejb invocation
        writer.println(bean.sayHello()+"<br>");

        // fetch value set by deployer
        writer.println("EmpNo="+empNo+"<br>");

        // make a db connection
        writer.println("db="+getConnection()+"<br>");
    }

    public Connection getConnection() {
      Connection conn = null; 
  
      try {
          if (db != null) {
              conn = db.getConnection();
          }
      } catch (Exception e) {
          e.printStackTrace();
      }
      return conn;
    }

    // The following is the pre-2.5 way to do it.
/*

   public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        res.setContentType("text/html");

        PrintWriter writer = res.getWriter();

        InitialContext ctx = new InitialContext();
        Object obj = ctx.lookup("java:comp/env/ejb/Hello");

        HelloHome ejbHome = (HelloHome)
                    PortableRemoteObject.narrow(obj,HelloHome.class);
        HelloObject bean = ejbHome.create();

        // ejb invocation
        writer.println(bean.sayHello()+"<br>");

        // fetch value set by deployer
        Context myEnv = (Context) ctx.lookup("java:comp/env");
        Integer empNoInteger = (Integer) myEnv.lookup("EmpNo");
        int empNo = empNoInteger.intValue();

        writer.println("EmpNo="+empNo+"<br>");

        // make a db connection
        writer.println("db="+getConnection()+"<br>");
    }

    public Connection getConnection() {

        Context initCtx = new InitialContext();
        javax.sql.DataSource db = 
           (javax.sql.DataSource) initCtx.lookup("java:comp/env/jdbc/OracleDS");

        Connection conn = null;

        try {
            if (db != null) {
                conn = db.getConnection();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }
*/
}

戻る 次へ
Oracle
Copyright © 2006 Oracle Corporation.

All Rights Reserved.
目次
目次
索引
索引