<jsp:useBean id="hoge" class="test.TestBean" />
<jsp:useBean>のclassとtypeの違い
<jsp:useBean>のclassとtypeは、機能が似ています。この2つの違いについては、SJC-WCの試験でもよく出題される部分です。
<jsp:useBean>で考えられるパターンごとに説明していきます。
classのみ指定
サンプルコード(hoge.jsp)
サンプルコード(hoge.jsp - コンパイル済み)
test.TestBean hoge = null; synchronized (_jspx_page_context) { hoge = (test.TestBean) _jspx_page_context.getAttribute("hoge", PageContext.PAGE_SCOPE); if (hoge == null){ hoge = new test.TestBean(); _jspx_page_context.setAttribute("hoge", hoge, PageContext.PAGE_SCOPE); } }
最初にpageContextから"hoge"を持つ属性を取得しようとします。
早い話は、既存の同名のインスタンスを探しだそうとします。
そして、classの場合はインスタンスが取得できなかった場合、新たにインスタンスを作成します。
typeのみ指定
サンプルコード(hoge.jsp)
<jsp:useBean id="hoge" type="test.TestBean" />
サンプルコード(hoge.jsp - コンパイル済み)
test.TestBean hoge = null; synchronized (_jspx_page_context) { hoge = (test.TestBean) _jspx_page_context.getAttribute("hoge", PageContext.PAGE_SCOPE); if (hoge == null){ throw new java.lang.InstantiationException("bean hoge not found within scope"); } }
class同様、最初にpageContextから"hoge"を持つ属性を取得しようとします。
しかし、lassの場合はインスタンスが取得できなかった場合、新たにインスタンスを作成しません。
例外を投げて終了します。
classとtypeを両方指定
サンプルコード(hoge.jsp)
<jsp:useBean id="hoge" type="test.TestBeanInterface" class="test.TestBean" />
サンプルコード(hoge.jsp - コンパイル済み)
test.TestBeanInterface hoge = null; synchronized (_jspx_page_context) { hoge = (test.TestBeanInterface) _jspx_page_context.getAttribute("hoge", PageContext.PAGE_SCOPE); if (hoge == null){ hoge = new test.TestBean(); _jspx_page_context.setAttribute("hoge", hoge, PageContext.PAGE_SCOPE); } }
(TestBeanはTestBeanInterfaceを実装していると仮定してください)
typeでは抽象クラスやインターフェースも指定できます。
classで抽象クラスやインターフェースを指定することはできません。
typeのみ指定した場合、新たにインスタンスを作成してしまうと抽象クラスやインターフェースも作成しようとします。
抽象クラスやインターフェースはインスタンス化できないので、コンパイルエラーになります。
そのため、typeでは新たにインスタンスを作成しようとしません。
beanNameの使用
サンプルコード(hoge.jsp)
<jsp:useBean id="hoge" type="test.TestBean" beanName="test.TestBean" />
サンプルコード(hoge.jsp - コンパイル済み)
test.TestBeanInterface hoge = null; synchronized (_jspx_page_context) { hoge = (test.TestBean) _jspx_page_context.getAttribute("hoge", PageContext.PAGE_SCOPE); if (hoge == null){ try { hoge = (test.TestBean) java.beans.Beans.instantiate( this.getClass().getClassLoader(), "test.TestBean"); } catch (ClassNotFoundException exc) { throw new InstantiationException(exc.getMessage()); } catch (Exception exc) { throw new ServletException("Cannot create bean of class " + "test.TestBean", exc); } _jspx_page_context.setAttribute("hoge", hoge, PageContext.PAGE_SCOPE); } }
まず、beanNameを使用する場合はtypeが必須になります。
この2つの属性を併用することで、スコープ内にインスタンスがない場合は新たにインスタンスを作成するようになります。
ですが、インスタンスの生成方法がclassのときとは異なります。
コンパイル済みのコードを見ると、java.beans.Beans.instantiate()メソッドでインスタンスを作成します。
このメソッドに関する説明は省略します(SJC-WCの試験範囲ではないため)。
試験対策 書籍