Oracle Containers for J2EE サーブレット開発者ガイド 10g(10.1.3.1.0) B31859-01 |
|
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
フラグを確認して、注釈を処理するかどうか判断します。 version
が2.4
以前のバージョンに設定されている場合、サーブレット・コンテナはいずれの注釈も処理しません。
metadata-complete
がサーブレット2.4のデフォルト値であるtrue
に設定されている場合、サーブレット・コンテナはアプリケーションのクラス・ファイル内にあるすべてのサーブレット注釈を無視します。 metadata-complete
属性がない、またはサーブレット2.5のデフォルト値であるfalse
に設定されており、version
が2.5
に設定されている場合、サーブレット・コンテナはサーブレット注釈のアプリケーションのクラス・ファイルを検証し、次のように注釈をサポートします。
WEB-INF/
ディレクトリ内またはWEB-INF/lib/
ディレクトリの下のJARファイルにあるWebアプリケーションのクラスに対する注釈参照のためにリソースまたはサービス参照を検査します。また、サーブレット・コンテナは、MANIFEST.MF
内にリストされるJARファイルへの注釈サポートも提供します。
Resource
、EJB
またはWebServiceRef
注釈内の情報の一部をオーバーライドできます。 次の仕様では、デプロイメント・ディスクリプタ・エントリを使用して注釈情報をオーバーライドする場合のルールが説明されています。
Some resource(s) and/or service(s) to be injected cannot be found forclass name
.class name
will not be put to service.
PostConstruct
注釈でマークされたメソッド(ある場合)を起動して、挿入したリソースを初期化する機会をサーブレットに与える必要があります。 「PostConstruct注釈」を参照してください。
PreDestroy
注釈でマークされたメソッド(ある場合)を起動して、挿入したリソースを解放する機会をサーブレットに与える必要があります。 「PreDestroy注釈」を参照してください。
この項では、OC4Jがサポートする注釈を説明します。
アプリケーション・コンポーネントのフィールドまたはメソッドの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
注釈を使用して、データソースやJMS宛先、環境エントリなどのリソースに対する参照を宣言します。 この注釈を使用する場合、デプロイメント・ディスクリプタ内の<resource-ref>
、<message-destination-ref>
、<env-ref>、
または<resource-env-ref>
要素で参照を宣言する必要はありません。
Resource
注釈をフィールドまたはsetterメソッドに適用する場合、OC4Jは注釈で宣言されたリソースに対する参照を挿入し、リソースのJNDI名に参照をマッピングします。 注釈をクラスに適用する場合、注釈はアプリケーションが実行時に参照するリソースを宣言します。
挿入はそれぞれJNDIルックアップに対応します。 注釈でJNDI名を明示的に指定しない場合、クラスの完全修飾名と結合したフィールド名をJNDI名として使用します。 たとえば、パッケージcom.example
内のクラスMyApp
のmyDb
という名のフィールドのデフォルト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
注釈は次の形式で複数の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 { //... }
すべてのその他のリソース挿入が完了した後、いずれかのライフサイクル・メソッドがインスタンスでコールされる前に、OC4JはメソッドをPostConstruct
注釈を使用して起動します。 これにより、コンポーネントは作成後の処理が可能になります。 クラスに他の注釈がない場合でも、OC4Jはこのメソッドを起動します。
PostConstruct
注釈の例を次に示します。
@PostConstruct void doPostInjectionProcessing { //...
OC4Jは、サーブレットをサービスから取り出す前に、PreDestroy
注釈を使用してメソッドを起動します。 これにより、サーブレットは挿入されたリソースを解放します。 クラスに他の注釈がない場合でも、OC4Jはこのメソッドを起動します。
PreDestroy
注釈の例を次に示します。
@PreDestroy void doPreDestroyProcessing { //... }
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
注釈は、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
注釈を使用した注釈付けは、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
注釈は、アプリケーションのセキュリティ・モデルを構成するすべてのセキュリティ・ロールを定義します。 この注釈をクラスで指定し、注釈を付けたクラスのメソッド内からテスト可能なロールを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
注釈は、デプロイメント・ディスクリプタの<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仕様を参照してください。
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
public
、private
など)を付けられます。
Class A { @Resource private DataSource myDS; // Injected resource not visible in class B //... } Class B extends Class A { public DataSource myDS; // Not a resource, needs to do JNDI lookup //... }
注釈を、サーブレットのバージョン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
<?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>
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; } */ }
|
![]() Copyright © 2006 Oracle Corporation. All Rights Reserved. |
|