posts - 4,comments - 30,trackbacks - 0
          在日本,Seasar2這個(gè)框架十分的流行。Seasar2其實(shí)就是類似于Spring的一個(gè)開源框架

          大家有興趣的話,可以去官方網(wǎng)站看看: http://www.seasar.org/index.html

          中文版現(xiàn)在還沒完善,大家可能要用日文或則英文來(lái)了解

          下面簡(jiǎn)單介紹一下:

          所謂“Seasar2”就是一個(gè)“輕量級(jí)容器”,面向無(wú)法擺脫“Java 應(yīng)用開發(fā)”之煩惱的所謂“開發(fā)者”,它能夠保證開發(fā)的“高生產(chǎn)率和高品質(zhì)”。并且同“其它輕量級(jí)容器”不同的是,“完全不需要書寫設(shè)定文件”,“就算是應(yīng)用程序發(fā)生改動(dòng)也無(wú)需再次起動(dòng)即可直接識(shí)別變更,因此具有腳本語(yǔ)言的靈活性”。

          為了不用寫設(shè)定文件也能夠運(yùn)行,Convention over Configuration的思想得以采用。Convention over Configuration就是指,“只要遵守一個(gè)適當(dāng)?shù)囊?guī)約,即使不用進(jìn)行非常麻煩的設(shè)定,框架結(jié)構(gòu)也可以自動(dòng)替我們搞定的思想”,這一思想是Ruby on Rails中所倡導(dǎo)的。Seasar2的Convention over Configuration是從Ruby on Rails 那里得到的提示而產(chǎn)生的。

          使用Seasar2的話,對(duì)于僅僅需要維護(hù)數(shù)據(jù)表這樣簡(jiǎn)單的應(yīng)用,可以在不到3分鐘的時(shí)間里作成。

          應(yīng)用程序發(fā)生改動(dòng)之時(shí)也無(wú)需啟動(dòng)便可立即識(shí)別變更的機(jī)能在Seasar2里被稱為HOT deploy



          安裝:

          S2需要安裝JDK1.4 or JDK1.5。

          將S2xxx.zip解壓之后的seasar2目錄引入到Eclipse、「文件→導(dǎo)入→既存的工程」。

          使用Seasar2基本功能(S2Container, S2AOP)的時(shí)候、CLASSPATH的下面必須包含以下文件。

          • lib/aopalliance-1.0.jar
          • lib/commons-logging-1.1.jar
          • lib/javassist-3.4.ga.jar
          • lib/ognl-2.6.9-patch-20070624.jar
          • lib/s2-framework-2.x.x.jar
          • lib/geronimo-j2ee_1.4_spec-1.0.jar (參考下面)
          • lib/portlet-api-1.0.jar (任選項(xiàng))
          • lib/log4j-1.2.13.jar (任選項(xiàng))
          • resources/log4j.properties (任選項(xiàng))
          • resources/aop.dicon (任選項(xiàng))

          使用Seasar2的擴(kuò)張機(jī)能(S2JTA, S2DBCP, S2JDBC, S2Unit, S2Tx, S2DataSet)的時(shí)候必須要將以下文件追加到CLASSPATH里面。

          • lib/junit-3.8.2.jar
          • lib/poi-2.5-final-20040804.jar
          • lib/s2-extension-2.x.x.jar
          • lib/geronimo-jta_1.1_spec-1.0.jar (參考下面)
          • lib/geronimo-ejb_2.1_spec-1.0.jar (參考下面)
          • resources/jdbc.dicon

          根據(jù)應(yīng)用軟件所需的執(zhí)行環(huán)境、選擇以下需要引用的文件[geronimo-j2ee_1.4_spec-1.0.jar、geronimo-jta_1.0.1B_spec-1.0.jar、geronimo-ejb_2.1_spec-1.0.jar]

          環(huán)境geronimo-j2ee_1.4_spec-1.0.jargeronimo-jta_1.1_spec-1.0.jargeronimo-ejb_2.1_spec-1.0.jar
          不完全對(duì)應(yīng)J2EE的Servlet container
          (Tomcat等)
          不要
          (使用S2JTA,S2Tx的時(shí)候)

          (使用S2Tiger的時(shí)候)
          完全對(duì)應(yīng)J2EE的應(yīng)用服務(wù)器
          (JBoss, WebSphere, WebLogic等)
          不要不要不要
          獨(dú)立
          (使用S2JTA,S2Tx時(shí)候)
          不要不要

          為了讓大家更簡(jiǎn)單的體驗(yàn)數(shù)據(jù)庫(kù)機(jī)能、使用了HSQLDB作為RDBMS。為了能夠體驗(yàn)Oracle機(jī)能、準(zhǔn)備了hsql/sql/demo-oracle.sql。SQL*Plus等執(zhí)行了之后、請(qǐng)根據(jù)環(huán)境的需要改寫jdbc.dicon的XADataSourceImpl的設(shè)定項(xiàng)目

          請(qǐng)使用S2Container用的插件Kijimuna

          想使用EJB3anoteshon的情況下、將 S2TigerXXX.zip解壓縮后的s2-tiger目錄引入Eclipse、「文件→導(dǎo)入→既存的工程」。 在Seasar2的設(shè)定基礎(chǔ)上、必需要將以下的文件追加到CLASSPATH里面。

          • lib/s2-tiger-x.x.x.jar
          • resources/jdbc.dicon

          想使用Tigeranoteshon的情況、將S2TigerXXX.zip解凍后的s2-tiger目錄引入Eclipse、「文件→進(jìn)口→既存的項(xiàng)目」。 在Seasar2的設(shè)定基礎(chǔ)上、必需要將以下的文件追加到CLASSPATH里面。

          • lib/s2-tiger-x.x.x.jar

          ?

          快速上手

          S2Container,就是進(jìn)行Dependency Injection(注:依賴注入——譯者)(以后略稱為DI)的一個(gè)輕量級(jí)容器。DI,就是Interface和實(shí)裝分離,程序相互之間僅通過(guò)Interface來(lái)會(huì)話的一種思考方式。

          最初的一步

          讓我們趕快試一試吧。登場(chǎng)人物如下。

          • 問(wèn)候語(yǔ)類
            • 返回問(wèn)候語(yǔ)的字符串。
          • 問(wèn)候客戶端類
            • 從問(wèn)候類獲得問(wèn)候語(yǔ)(字符串)并輸出到終端屏幕。
          • 問(wèn)候語(yǔ)應(yīng)用主類
            • 啟動(dòng)用的類。用來(lái)組織問(wèn)候語(yǔ)類和問(wèn)候語(yǔ)使用者類的組成方式。
          Greeting.java

          問(wèn)侯語(yǔ)的Interface。

          package examples.di;
          
          public interface Greeting {
          
              String greet();
          }
          
          GreetingImpl.java

          問(wèn)候語(yǔ)的實(shí)裝。

          package examples.di.impl;
          
          import examples.di.Greeting;
          
          public class GreetingImpl implements Greeting {
          
              public String greet() {
                  return "Hello World!";
              }
          }
          
          GreetingClient.java

          使用問(wèn)候語(yǔ)的使用者客戶端Interface。

          package examples.di;
          
          public interface GreetingClient {
          
              void execute();
          }
          
          GreetingClientImpl.java

          使用問(wèn)候語(yǔ)的客戶端的實(shí)裝。不是直接使用這個(gè)GreetngImpl(實(shí)裝),而是通過(guò)Greeting(Interface)來(lái)實(shí)現(xiàn)問(wèn)候的機(jī)能。

          package examples.di.impl;
          
          import examples.di.Greeting;
          import examples.di.GreetingClient;
          
          public class GreetingClientImpl implements GreetingClient {
          
              private Greeting greeting;
          
              public void setGreeting(Greeting greeting) {
                  this.greeting = greeting;
              }
          
              public void execute() {
                  System.out.println(greeting.greet());
              }
          }
          

          機(jī)能提供端和使用端的準(zhǔn)備都完成了。下面我們就執(zhí)行一下試試吧。

          GreetingMain.java
          package examples.di.main;
          
          import examples.di.Greeting;
          import examples.di.impl.GreetingClientImpl;
          import examples.di.impl.GreetingImpl;
          
          public class GreetingMain {
          
              public static void main(String[] args) {
                  Greeting greeting = new GreetingImpl();
                  GreetingClientImpl greetingClient = new GreetingClientImpl();
                  greetingClient.setGreeting(greeting);
                  greetingClient.execute();
              }
          }
          

          實(shí)行結(jié)果如下。

          Hello World!
          

          象這樣機(jī)能的使用者(GreetingClientImpl)經(jīng)由Interface(Greeting)的中介來(lái)使用機(jī)能,具體的機(jī)能對(duì)象(既Interface的實(shí)裝類)在實(shí)行的時(shí)候由第三者(在這里是GreetingMain)來(lái)提供的情況,就是DI的基本思考方法。

          但是,如果象GreetingMain中那樣實(shí)裝類的設(shè)定內(nèi)容直接被寫出來(lái)的話,一旦實(shí)裝類需要變更的時(shí)候源代碼也必須跟著修正。為了避免這個(gè)麻煩,DIContainer就登場(chǎng)了。把實(shí)裝設(shè)定抽出到一個(gè)設(shè)定文件中,由DIContainer把這個(gè)設(shè)定文件讀入并組織對(duì)象運(yùn)行。

          那么,讓我們?cè)囍褎偛诺奶岬降哪莻€(gè)設(shè)定文件的內(nèi)容寫一下。S2Container中,設(shè)定文件的后綴是".dicon"。

          GreetingMain2.dicon
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE components PUBLIC
          "-//SEASAR//DTD S2Container 2.3//EN"
          "http://www.seasar.org/dtd/components23.dtd">
          <components>
          <component name="greeting"
          class="examples.di.impl.GreetingImpl"/>
          <component name="greetingClient"
          class="examples.di.impl.GreetingClientImpl">
          <property name="greeting">greeting</property>
          </component>
          </components>

          ?

          <component name="greeting"
          class="examples.di.impl.GreetingImpl"/>

          上文記載的是組件的定義。在這里,相當(dāng)于如下的Java代碼。

          Greeting greeting = new GreetingImpl();
          

          component標(biāo)簽的name屬性指定了組件的名稱,class屬性指定了組件的Java類文件名。下文就是greetingClient的設(shè)定。

          <component name="greetingClient"
          class="examples.di.impl.GreetingClientImpl">
          <property name="greeting">greeting</property>
          </component>

          property標(biāo)簽的name屬性指定了組件Java類中的屬性名,標(biāo)簽的定義體則指定了一個(gè)組件名稱。這個(gè)設(shè)定相當(dāng)于如下Java代碼。組件名要注意不要用["]括起來(lái)。用["]括起來(lái)的話就會(huì)被當(dāng)作字符串來(lái)處理了。

          GreetingClientImpl greetingClient = new GreetingClientImpl();
          greetingClient.setGreeting(greeting);
          

          利用S2Container的起動(dòng)類的內(nèi)容如下。

          GreetingMain2.java
          package examples.di.main;
          
          import org.seasar.framework.container.S2Container;
          import org.seasar.framework.container.factory.S2ContainerFactory;
          
          import examples.di.GreetingClient;
          
          public class GreetingMain2 {
          
              private static final String PATH =
                  "examples/di/dicon/GreetingMain2.dicon";
          
              public static void main(String[] args) {
                  S2Container container =
                      S2ContainerFactory.create(PATH);
                  container.init();
                  GreetingClient greetingClient = (GreetingClient)
                      container.getComponent("greetingClient");
                  greetingClient.execute();
              }
          }
          

          S2Container,是由S2ContainerFactory#create(String path)做成的。更加詳細(xì)的內(nèi)容請(qǐng)參照S2Container的生成

          組件(greetingClient),是由S2Container#getComponent(String componentName)的方法取得的。詳細(xì)內(nèi)容請(qǐng)參照組件的取得

          實(shí)行結(jié)果同先前一樣表示如下。

          Hello World!
          

          經(jīng)常同DI一起使用的是AOP。AOP是指、將日志等的輸出分散到復(fù)數(shù)個(gè)類中的邏輯模塊化的一種技術(shù)。那么、讓我們不修改已經(jīng)作成的GreetingImpl、GreetingClinetImpl的源代碼?試著將日志(追蹤)輸出。 適用于AOP的設(shè)定文件如下。

          GreetingMain3.dicon
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE components PUBLIC
          "-//SEASAR//DTD S2Container 2.3//EN"
          "http://www.seasar.org/dtd/components23.dtd">
          <components>
          <include path="aop.dicon"/>
          <component name="greeting"
          class="examples.di.impl.GreetingImpl">
          <aspect>aop.traceInterceptor</aspect>
          </component>
          <component name="greetingClient"
          class="examples.di.impl.GreetingClientImpl">
          <property name="greeting">greeting</property>
          <aspect>aop.traceInterceptor</aspect>
          </component>
          </components>

          Seasar2中,經(jīng)常使用的AOP模塊在aop.dicon中預(yù)先定義。 象下面這樣、使用include標(biāo)簽。 更加詳細(xì)的?敬請(qǐng)參照S2Container定義的分解和引入

          <include path="aop.dicon"/>
          

          對(duì)于在組件中適用的AOP來(lái)說(shuō)?我們component標(biāo)簽的字標(biāo)簽 aspect標(biāo)簽的正文中指定AOP的模塊名稱。aop.traceInterceptor是AOP模塊的名字。

          <aspect>aop.traceInterceptor</aspect>
          

          AOP的設(shè)定如上所述。那么就讓我們執(zhí)行一下GreetingMain3吧。同GreetingMain2不同的僅僅是設(shè)定文件的路徑而已。

          GreetingMain3.java
          package examples.di.main;
          
          import org.seasar.framework.container.S2Container;
          import org.seasar.framework.container.factory.S2ContainerFactory;
          
          import examples.di.GreetingClient;
          
          public class GreetingMain3 {
          
              private static final String PATH =
                  "examples/di/dicon/GreetingMain3.dicon";
          
              public static void main(String[] args) {
                  S2Container container =
                      S2ContainerFactory.create(PATH);
                  GreetingClient greetingClient = (GreetingClient)
                      container.getComponent("greetingClient");
                  greetingClient.execute();
              }
          }
          

          執(zhí)行結(jié)果如下。可以明白一點(diǎn),沒有修改源代碼,日志就被輸出了。

          DEBUG 2005-10-11 21:01:49,655 [main] BEGIN examples.di.impl.GreetingClientImpl#execute()
          DEBUG 2005-10-11 21:01:49,665 [main] BEGIN examples.di.impl.GreetingImpl#greet()
          DEBUG 2005-10-11 21:01:49,665 [main] END examples.di.impl.GreetingImpl#greet() : Hello World!
          Hello World!
          DEBUG 2005-10-11 21:01:49,675 [main] END examples.di.impl.GreetingClientImpl#execute() : null
          

          這樣、S2Container的基本使用方法就被掌握了。

          更進(jìn)一步

          但是,不管怎么說(shuō)書寫設(shè)定文件都是一件麻煩的事啊。在S2Container中,為了盡可能的減少設(shè)定文件的記述量、采用了如下的概念。

          就是說(shuō)制定一個(gè)適當(dāng)?shù)囊?guī)約,遵守這個(gè)規(guī)約的話?無(wú)需什么設(shè)定也可以運(yùn)作。比如說(shuō),剛才的設(shè)定文件中,象下面這樣明確地指定屬性的部分存在著。

          <component name="greetingClient"
          class="examples.di.impl.GreetingClientImpl">
          <property name="greeting">greeting</property>
          </component>

          S2Container中、屬性的類型是Interface的情形下? 如果要將屬性類型的實(shí)裝組件注冊(cè)進(jìn)軟件容器中, 不需要什么特殊的設(shè)定也可以自動(dòng)得運(yùn)作DI的機(jī)能。 這就是,如果遵守DI中推薦的所謂“屬性類型用Interface定義”的規(guī)則,S2Container會(huì)自動(dòng)地處理一切。

          雖然一說(shuō)到規(guī)約就容易產(chǎn)生麻煩之類的想法,“推薦而已,如果遵守的話就能使開發(fā)愉快”的話,遵守規(guī)約的動(dòng)機(jī)就產(chǎn)生了。這才是問(wèn)題的重點(diǎn)。

          如上的設(shè)定,可以做如下化簡(jiǎn)

          <component name="greetingClient"
          class="examples.di.impl.GreetingClientImpl">
          </component>

          實(shí)際上?剛才的AOP的例子也適用“Convention over Configuration”。 通常在AOP中,AOP的模塊在什么地方適用是由pointcut指定的,S2AOP的情況下? 如果遵守所謂“使用Interface”這個(gè)推薦的規(guī)約,不指定pointcut,自動(dòng)的適用于在Interface中定義的所有方法。因?yàn)橛羞@個(gè)機(jī)能,在剛才的那個(gè)例子中,就沒有必要指定pointcut。

          雖然根據(jù)“Convention over Configuration”,DI和AOP的設(shè)定可以得以簡(jiǎn)化,需要處理的組件數(shù)增加了、僅僅組件的注冊(cè)也會(huì)變成一個(gè)非常累的作業(yè)。那么這個(gè)組件注冊(cè)自動(dòng)化就叫做組件自動(dòng)注冊(cè)機(jī)能。 剛才的GreetingImpl、GreetingClientImpl的注冊(cè)自動(dòng)化如下。

          <component
          class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
          <initMethod name="addClassPattern">
          <arg>"examples.di.impl"</arg>
          <arg>".*Impl"</arg>
          </initMethod>
          </component>

          FileSystemComponentAutoRegister組件將addClassPattern方法指定的類從文件系統(tǒng)中探尋出來(lái),自動(dòng)注冊(cè)到S2Container中。關(guān)于initMethod標(biāo)簽,請(qǐng)參照方法函數(shù)注入

          addClassPattern方法的第一個(gè)參數(shù)是想要注冊(cè)的組件的包的名字。 子包的內(nèi)容也會(huì)用回歸的方式檢索。第二個(gè)參數(shù)是類的名字。可以使用正則表達(dá)式。也可以用“,”做分隔符指定復(fù)數(shù)個(gè)設(shè)定。

          根據(jù)組件自動(dòng)注冊(cè)原則,即使后續(xù)追加組件的情況下,也沒有必要追加設(shè)定,這樣手續(xù)就大大地簡(jiǎn)化了。

          如果組件的自動(dòng)化注冊(cè)可以了,接下來(lái)就會(huì)想讓AOP的注冊(cè)也自動(dòng)化了吧。剛才的GreetingImpl、GreetingClientImp的AOP注冊(cè)自動(dòng)化的設(shè)定如下。

          <include path="aop.dicon"/>
          ...
          <component
          class="org.seasar.framework.container.autoregister.AspectAutoRegister">
          <property name="interceptor">aop.traceInterceptor</property>
          <initMethod name="addClassPattern">
          <arg>"examples.di.impl"</arg>
          <arg>".*Impl"</arg>
          </initMethod>
          </component>

          用interceptor屬性指定AOP的名稱。addClassPattern方法同組件的自動(dòng)化注冊(cè)時(shí)的用法一樣,這里就不做特殊的說(shuō)明了。 組件自動(dòng)化注冊(cè)和AOP自動(dòng)化注冊(cè)的例子如下。

          GreetingMain4.dicon
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.3//EN"
          "http://www.seasar.org/dtd/components23.dtd"> <components>
          <include path="aop.dicon"/> <component
          class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
          <initMethod name="addClassPattern">
          <arg>"examples.di.impl"</arg>
          <arg>".*Impl"</arg>
          </initMethod>
          </component> <component
          class="org.seasar.framework.container.autoregister.AspectAutoRegister">
          <property name="interceptor">aop.traceInterceptor</property>
          <initMethod name="addClassPattern">
          <arg>"examples.di.impl"</arg>
          <arg>".*Impl"</arg>
          </initMethod>
          </component>
          </components>

          那么來(lái)執(zhí)行一下GreetingMain4吧。 自動(dòng)注冊(cè)的情況下,S2Container#init()和S2Container#destroy()的調(diào)用是必要的。

          GreetingMain4.java
          package examples.di.main;
          
          import org.seasar.framework.container.S2Container;
          import org.seasar.framework.container.factory.S2ContainerFactory;
          
          import examples.di.GreetingClient;
          
          public class GreetingMain4 {
          
              private static final String PATH =
                  "examples/di/dicon/GreetingMain4.dicon";
          
              public static void main(String[] args) {
                  S2Container container =
                      S2ContainerFactory.create(PATH);
                  container.init();
                  try {
                      GreetingClient greetingClient = (GreetingClient)
                          container.getComponent("greetingClient");
                      greetingClient.execute();
                  } finally {
                      container.destroy();
                  }
              }
          }
          

          執(zhí)行的結(jié)果同GreetingMain3一樣如下列出。

          DEBUG 2005-10-12 16:00:08,093 [main] BEGIN examples.di.impl.GreetingClientImpl#execute()
          DEBUG 2005-10-12 16:00:08,103 [main] BEGIN examples.di.impl.GreetingImpl#greet()
          DEBUG 2005-10-12 16:00:08,103 [main] END examples.di.impl.GreetingImpl#greet() : Hello World!
          Hello World!
          DEBUG 2005-10-12 16:00:08,103 [main] END examples.di.impl.GreetingClientImpl#execute() : null
          

          大多數(shù)的情況下?自動(dòng)注冊(cè)和自動(dòng)綁定的組合方式都能順利的進(jìn)行下去。不想要自動(dòng)注冊(cè)的組件存在的情況下,自動(dòng)注冊(cè)組件中準(zhǔn)備了addIgnoreClassPattern方法,可以指定自動(dòng)注冊(cè)外的組件。

          不想要自動(dòng)綁定的屬性存在的情況下,使用Binding備注碼,不使用設(shè)定文件也可以做細(xì)節(jié)的調(diào)整。

          使用Hotswap的話?應(yīng)用程序在運(yùn)行中重新書寫更換類文件,馬上就能夠直接測(cè)試結(jié)果。不需要一個(gè)一個(gè)地將應(yīng)用程序在啟動(dòng),因此開發(fā)的效率能夠得到大幅度的提高。

          現(xiàn)在,關(guān)于S2Container的高級(jí)使用方法也可以掌握了。這之后嘛,只要根據(jù)需要參照對(duì)應(yīng)的操作手冊(cè)就可以了。

          S2Container參考

          需要作成的文件

          為了使用S2Container,定義文件的做成是必要的。定義文件就像是為了組織組件而制作的設(shè)計(jì)書一樣的東西。形式為XML,后綴為dicon。

          S2Container的定義

          S2Container的定義、象下面這樣。

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.3//EN"
          "http://www.seasar.org/dtd/components23.dtd">
          <components>
              <component name="..." class="...">
                      ...
              </component>
              <component name="..." class="...">
                      ...
              </component>
          </components>
          

          DOCTYPE是不能省略的。dicon做成的時(shí)候、請(qǐng)將前述例子拷貝粘貼。根是components標(biāo)簽。每一個(gè)組件用component標(biāo)簽定義。用component標(biāo)簽的class屬性指定組件的類的全名。在name屬性中、指定組件的名稱。詳細(xì)內(nèi)容請(qǐng)參照S2Container定義標(biāo)簽參考

          <components>
              <component name="hoge" class="examples.dicon.HogeImpl"/>
          </components>
          

          S2Container的生成

          S2Container的生成方法有兩種。

          • 使用SingletonS2ContainerFactory。
          • 使用S2ContainerFactory。

          使用SingletonS2ContainerFactory

          使用SingletonS2ContainerFactory的情況下,使用如下方法。

          - org.seasar.framework.container.factory.SingletonS2ContainerFactory#init()

          定義文件使用的是CLASSPATH所指定的路徑中存在的app.dicon。

          做成的S2Container,無(wú)論在什么地方都是可以從如下方法中取得。

          - org.seasar.framework.container.factory.SingletonS2ContainerFactory#getContainer()

          SingletonS2ContainerFactory.init();
          ...
          S2Container container = SingletonS2ContainerFactory.getContainer();
          

          定義文件的路徑需要被指定的情況下應(yīng)在調(diào)用init()之前執(zhí)行如下方法。

          - org.seasar.framework.container.factory.SingletonS2ContainerFactory#setConfigPath(String Path)

          參數(shù)path是相對(duì)于以CLASSPATH指定的路徑為根的定義文件的絕對(duì)路徑。例如,WEB-INF/classes/aaa.dicon 的情況下就是aaa.dicon,WEB-INF/classes/aaa/bbb/ccc.dicon的情況下就是aaa/bbb/ccc.dicon。分隔符在Windows和Unix下都是/。

          private static final String PATH = "aaa/bbb/ccc.dicon";
          ...
          SingletonS2ContainerFactory.setConfigPath(PATH);
          SingletonS2ContainerFactory.init();
          ...
          S2Container container = SingletonS2ContainerFactory.getContainer();
          

          使用S2ContainerFactory

          使用S2ContainerFactory的場(chǎng)合下,使用如下方法。

          - org.seasar.framework.container.factory.S2ContainerFactory#create(String path)

          S2Container生成之后需要許呼叫下一個(gè)方法。

          - org.seasar.framework.container.S2Container#init()

          private static final String PATH = "aaa/bbb/ccc.dicon";
          ...
          S2Container container = S2ContainerFactory.create(PATH);
          container.init();
          

          用這個(gè)方法取得的組件的實(shí)例,有必要進(jìn)行在應(yīng)用中的管理。

          組件的取得

          從S2Container中將組件取出來(lái),使用下面的方法。

          - org.seasar.framework.container.S2Container#getComponent(Object componentKey)

          參數(shù)中指定的是組件的類或者是組件的名稱。詳細(xì)的請(qǐng)參照component標(biāo)簽。要指定組件的類,只要是 組件 instanceof 類 的操作返回為true的類就能夠指定。但是、S2Container中所指定的類對(duì)應(yīng)了好幾個(gè)實(shí)裝的組件的時(shí)候,S2Container將不能判斷返回哪一個(gè)組件為好,這樣就會(huì)發(fā)生TooManyRegistrationRuntimeException。請(qǐng)指定實(shí)裝組件為唯一的類。也可以用組件名稱取得組件。這種情況下也是同樣,用一個(gè)名稱的復(fù)數(shù)個(gè)組件被注冊(cè)的情況下,將發(fā)生TooManyRegistrationRuntimeException。指定組件名的場(chǎng)合下,因?yàn)橐部赡馨l(fā)生拼寫錯(cuò)誤,所以盡可能的指定組件的類為好。

          例)通過(guò)指定類來(lái)取得組件的場(chǎng)合

          S2Container container = S2ContainerFactory.create(PATH);
          Hoge hoge = (Hoge) container.getComponent(Hoge.class);
          

          例)通過(guò)指定組件名來(lái)取得組件場(chǎng)合

          S2Container container = S2ContainerFactory.create(PATH);
          Hoge hoge = (Hoge) container.getComponent("hoge");
          

          Dependency Injection的類型

          在Dependency Injection中,組件的構(gòu)成所必要的值是用構(gòu)造函數(shù)來(lái)設(shè)定(Constructor Injection),還是用設(shè)定函數(shù)來(lái)設(shè)定(Setter Injection),或者是用初始化函數(shù)來(lái)設(shè)定(Method Injection),這樣進(jìn)行分類。Method Injection是S2Container的本源。S2Container支持以上所有類型和混合類型。

          構(gòu)造函數(shù)?注入

          對(duì)構(gòu)造函數(shù)的參數(shù)進(jìn)行DI,這就是構(gòu)造函數(shù)注入。
          S2Container的定義文件中,記述如下內(nèi)容。

          • 組件的指定
            組件,用component標(biāo)簽來(lái)組建。用class指定對(duì)應(yīng)的類。
            也可以用name屬性給組件起名稱。
          • 構(gòu)造函數(shù)的參數(shù)的指定
            組件的構(gòu)造函數(shù)的參數(shù)用component標(biāo)簽的子標(biāo)簽arg標(biāo)簽來(lái)指定。
            值為字符串的時(shí)候,用雙引號(hào)(")括起來(lái)。
          <components>
              <component name="..." class="...">
                    <arg>...</arg>
              </component>
          </components>
          

          設(shè)定函數(shù)?注入

          設(shè)定函數(shù)注入是指對(duì)于任意一個(gè)屬性變量使用設(shè)定函數(shù)來(lái)行使DI。
          S2Container的定義文件中作如下內(nèi)容的記述。

          • 組件的指定
            組件的指定同構(gòu)造函數(shù)注入相同。
          • 屬性變量的指定
            組件的屬性變量用component標(biāo)簽的子標(biāo)簽property來(lái)指定。
            用name屬性來(lái)指定變量的名稱。
          <components>
              <component name="..." class="...">
                    <property name="...">...</property>
              </component>
          </components>
          

          方法函數(shù)?注入

          方法函數(shù)注入是指,通過(guò)任意一個(gè)函數(shù)的調(diào)用來(lái)完成DI的功能。
          S2Container的定義文件中,記述如下內(nèi)容。

          • 組件的指定
            組件的指定同構(gòu)造函數(shù)注入相同。
          • 初始化方法函數(shù)的指定
            使用initMethod標(biāo)簽,調(diào)用組件的任意一個(gè)方法函數(shù)。在name屬性中,指定方法函數(shù)的名稱。 用arg標(biāo)簽指定參數(shù),name屬性省略,在正文中,使用OGNL式也可以。
          <components>
              <component name="..." class="...">
                  <initMethod name="...">
                      <arg>...</arg>
                  </initMethod>
              </component>
          </components>
          

          S2Container定義的分割和引入

          所有的組件用一個(gè)文件來(lái)設(shè)定的話,很快就會(huì)變得臃腫而難以管理。因此,S2Container就具有了將組件的定義進(jìn)行復(fù)數(shù)個(gè)分割的機(jī)能和將多個(gè)分割的定義文件引入而組織成一個(gè)文件的機(jī)能。S2Container定義文件的引入方法如下。

          <components>
              <include path="bar.dicon"/>
          </components>
          

          include標(biāo)簽的path屬性被用來(lái)指定想要引入的S2Container定義文件的路徑。詳細(xì)情況請(qǐng)參照include標(biāo)簽
          組件的檢索順序,先是在自身注冊(cè)的文件中尋找組件,沒有找到所需組件的情況下,將按照include的順序在子定義文件中查找注冊(cè)到S2Container中的組件,最先找到的那個(gè)組件將被返回。

          <components>
              <include path="aaa.dicon"/>
              <include path="bbb.dicon"/>
              <component class="example.container.Foo" />
          </components>
          

          命名空間

          組件的定義被分割的情況下,為了不讓復(fù)數(shù)個(gè)組件的定義名稱發(fā)生沖突,可以用components標(biāo)簽的namespace屬性指定命名空間。

          foo.dicon
          <components namespace="foo">
              <component name="aaa" .../>
              <component name="bbb" ...>
                  <arg>aaa</arg>
              </component>
          </components>
          
          bar.dicon
          <components namespace="bar">
              <include path="foo.dicon"/>
              <component name="aaa" .../>
              <component name="bbb" ...>
                  <arg>aaa</arg>
              </component>
              <component name="ccc" ...>
                  <arg>foo.aaa</arg>
              </component>
          </components>
          
          app.dicon
          <components>
              <include path="bar.dicon"/>
          </components>
          

          在同一個(gè)組件定義文件中可以不需要指定命名空間而調(diào)用組件。調(diào)用其它S2Container文件中定義的組件時(shí),要在組件名前加上命名空間。foo.aaa 和 bar.aaa 雖然有相同名稱的組件,但是因?yàn)槊臻g的不同,就被認(rèn)為是不同的組件。

          實(shí)例(instance)管理

          在S2Container中,怎么樣對(duì)實(shí)例進(jìn)行管理,這個(gè)設(shè)定是用component標(biāo)簽的instance屬性。

          instance屬性說(shuō)明
          singleton(default)不論S2Container.getComponent()被調(diào)用多少次都返回同一個(gè)實(shí)例。
          prototypeS2Container.getComponent()每次被調(diào)用的時(shí)候都返回一個(gè)新的實(shí)例。
          request對(duì)應(yīng)每一個(gè)請(qǐng)求(request)做成一個(gè)實(shí)例。用name屬性中指定的名稱,組件被容納在請(qǐng)求中。使用request的場(chǎng)合下需要設(shè)定S2ContainerFilter
          session對(duì)應(yīng)每一個(gè)session做成一個(gè)實(shí)例。用name屬性中指定的名稱,組件被容納在session中。使用session的場(chǎng)合下需要設(shè)定S2ContainerFilter
          application使用Servlet的場(chǎng)合下,對(duì)應(yīng)每一個(gè)ServletContext做成一個(gè)實(shí)例。用name屬性中指定的名稱,組件被容納在ServletContext中。使用application的場(chǎng)合下需要設(shè)定S2ContainerFilter
          outer組件的實(shí)例在S2Container之外作成,從而僅僅行使Dependency Injection的功能。Aspect構(gòu)造函數(shù)注入不能適用。

          生存周期

          使用initMethod 和 destroyMethod組件的生存周期也可以用容器來(lái)管理。在S2Container的開始時(shí)用(S2Container.init())調(diào)用initMethod標(biāo)簽中指定的方法,S2Container結(jié)束時(shí)用(S2Container.destroy())調(diào)用destroyMethod標(biāo)簽中指定的方法。initMethod將按照容器中注冊(cè)的組件的順序來(lái)執(zhí)行組件,destroyMethod則按照相反的順序去執(zhí)行。instance屬性是singleton之外的情況下,指定了destroyMethod也會(huì)被忽視。java.util.HashMap#put()方法中初始化(給aaa賦值為111)?結(jié)束處理(給aaa賦值為null)的設(shè)定,向下面那樣。

          <components namespace="bar">
              <component name="map" class="java.util.HashMap">
                  <initMethod name="put">
                      <arg>"aaa"</arg>
                      <arg>111</arg>
                  </initMethod>
                  <destroyMethod name="put">
                      <arg>"aaa"</arg>
                      <arg>null</arg>
                  </destroyMethod>
              </component>
          </components>
          

          自動(dòng)綁定

          組件間的依存關(guān)系,類型是interface的場(chǎng)合時(shí),將由容器來(lái)自動(dòng)解決。這是在S2Container被默認(rèn)的,指定component標(biāo)簽的autoBinding屬性可以進(jìn)行更加細(xì)致的控制。

          autoBinding說(shuō)明
          auto(default)適用于構(gòu)造函數(shù)和屬性變量的自動(dòng)綁定。
          constructor適用于構(gòu)造函數(shù)的自動(dòng)綁定。
          property適用于屬性變量的自動(dòng)綁定。
          none只能對(duì)構(gòu)造函數(shù)、屬性變量進(jìn)行手動(dòng)綁定。

          構(gòu)造函數(shù)的自動(dòng)綁定規(guī)則如下所示。

          • 明確指定了構(gòu)造函數(shù)的參數(shù)的情況下,自動(dòng)綁定將不再適用。
          • 不屬于上述情況,如果是定義了沒有參數(shù)的默認(rèn)的構(gòu)造函數(shù)的話,對(duì)于這個(gè)構(gòu)造函數(shù),自動(dòng)綁定也不適用。
          • 不屬于上述情況,參數(shù)的類型全是interface并且參數(shù)數(shù)目最多的構(gòu)造函數(shù)將被使用。 這樣,對(duì)于從容器中取得參數(shù)類型的實(shí)裝組件,自動(dòng)綁定是適用的。
          • 如果不是以上情況,自動(dòng)綁定將不適用。

          屬性變量的自動(dòng)綁定規(guī)則如下。

          • 明確指定了屬性變量的情況下,自動(dòng)綁定將不適用。
          • 不屬于上述情況,如果在容器的注冊(cè)組件中存在著可以代入屬性變量中的同名組件,自動(dòng)綁定將適用于該組件。
          • 不屬于上述情況,屬性變量的類型是interface并且該屬性類型的實(shí)裝組件在容器中注冊(cè)了的話,自動(dòng)綁定是適用的。
          • 如果不是以上情況,自動(dòng)綁定將不適用。

          用property標(biāo)簽的bindingType屬性,可以更加細(xì)致的控制屬性變量。

          bindingType說(shuō)明
          must自動(dòng)綁定不適用的情況下?將會(huì)發(fā)生例外。
          should(default)自動(dòng)綁定不適用的情況下,將發(fā)出警告通知。
          may自動(dòng)綁定不適用的情況下,什么都不發(fā)生。
          noneautoBinding的屬性雖然是auto、property情況下,自動(dòng)綁定也不適用。

          在組件中利用S2Container

          不想讓組件依存于S2Container的情況下,根據(jù)組件的具體情況,在組件中需要調(diào)用S2Container的方法,這樣的場(chǎng)合也許會(huì)存在。S2Container自身也以container的名稱,自我注冊(cè)了。所以可以在arg,property標(biāo)簽的正文中指定container,從而取得容器的實(shí)例。還有,S2Container類型的setter方法定義好了后也可以做自動(dòng)綁定的設(shè)定。用arg,property標(biāo)簽指定container的情況下,向下面這樣進(jìn)行。

          <components>
              <component class="examples.dicon.BarImpl">
                  <arg>container</arg>
              </component>
          
              <component class="examples.dicon.FooImpl">
                  <property name="foo">container</property>
              </component>
          </components>
          

          S2ContainerServlet

          到此為止,在Java application中,是用明確表示的方法做成S2Container的,Web application的情況下,由誰(shuí)來(lái)作成S2Container呢?為了達(dá)到這個(gè)目的,準(zhǔn)備了以下的類。

          • org.seasar.framework.container.servlet#S2ContainerServlet

          為了使用S2ContainerServlet,在web.xml中記述如下項(xiàng)目。

          <servlet>
              <servlet-name>s2servlet</servlet-name>
              <servlet-class>org.seasar.framework.container.servlet.S2ContainerServlet</servlet-class>
              <init-param>
                  <param-name>configPath</param-name>
                  <param-value>app.dicon</param-value>
              </init-param>
              <init-param>
                  <param-name>debug</param-name>
                  <param-value>false</param-value>
              </init-param>
              <load-on-startup>1</load-on-startup>
          </servlet>
          
          <servlet-mapping>
              <servlet-name>s2servlet</servlet-name>
              <url-pattern>/s2servlet</url-pattern>
          </servlet-mapping>
          

          用configPath來(lái)指定作為根的S2Container的定義路徑。定義文件將放在WEB-INF/classes中。對(duì)于S2ContainerServlet,為了比其它的servlet更早的起動(dòng),請(qǐng)做load-on-startup標(biāo)簽的調(diào)整。S2ContainerServlet起動(dòng)之后,可以用如下的方法函數(shù)取得S2Container的實(shí)例。

          • org.seasar.framework.container.factory.SingletonS2ContainerFactory#getContainer()

          另外,S2Container的生命周期和S2ContainerServlet是連動(dòng)的。debug變量被設(shè)為true的話,按照以下的方法,可以將運(yùn)行中的S2Container再次起動(dòng)。xxx是Web application的context名。

          http://localhost:8080/xxx/s2servlet?command=restart
                      
          

          在使用了S2ContainerServlet的情況下,ServletContext將會(huì)作為一個(gè)組件可以用servletContext的名字來(lái)訪問(wèn)。

          app.dicon的角色

          根的S2Container的定義文件,按照慣例用app.dicon的名稱。通常放在WEB-INF/classes中就好了。

          AOP的適用

          在組件中AOP的適用情況也可以被設(shè)定。比如,想要在ArrayList中設(shè)定TraceInterceptor使用的情況下需要象下面這樣做。

          <components>
              <component name="traceInterceptor"
                         class="org.seasar.framework.aop.interceptors.TraceInterceptor"/>
              <component class="java.util.ArrayList">
                  <aspect>traceInterceptor</aspect>
              </component>
              <component class="java.util.Date">
                  <arg>0</arg>
                  <aspect pointcut="getTime, hashCode">traceInterceptor</aspect>
              </component>
          </components>
          

          aspect標(biāo)簽的正文中指定Interceptor的名字。pointcut的屬性中可以用逗號(hào)做分隔符指定AOP對(duì)象的方法的名字。pointcut的屬性沒有被指定的情況下,組件將把實(shí)裝的interface的所有方法函數(shù)作為AOP的對(duì)象。方法函數(shù)的名稱指定也可以用正則表達(dá)式(JDK1.4のregex)。這樣的定義例子如下。

          private static final String PATH =
              "examples/dicon/Aop.dicon";
          S2Container container = S2ContainerFactory.create(PATH);
          List list = (List) container.getComponent(List.class);
          list.size();
          Date date = (Date) container.getComponent(Date.class);
          date.getTime();
          date.hashCode();
          date.toString();
          

          執(zhí)行結(jié)果。

          BEGIN java.util.ArrayList#size()
          END java.util.ArrayList#size() : 0
          BEGIN java.util.Date#getTime()
          END java.util.Date#getTime() : 0
          BEGIN java.util.Date#hashCode()
          BEGIN java.util.Date#getTime()
          END java.util.Date#getTime() : 0
          END java.util.Date#hashCode() : 0
          BEGIN java.util.Date#getTime()
          END java.util.Date#getTime() : 0
          

          組件中也可以設(shè)定InterType的適用情況。比如,在Hoge中設(shè)定PropertyInterType的適用情況如下進(jìn)行。

          <components>
              <include path="aop.dicon"/>
              <component class="examples.Hoge">
                  <interType>aop.propertyInterType</aspect>
              </component>
          </components>
          

          在interType標(biāo)簽的正文中指定InterType的名稱。

          Meta數(shù)據(jù)

          在components、component、arg、property標(biāo)簽中也可以指定Meta數(shù)據(jù)。meta標(biāo)簽將作為需要指定Meta數(shù)據(jù)的標(biāo)簽的字標(biāo)簽來(lái)指定Meta數(shù)據(jù)。例如,想要在components標(biāo)簽中指定Meta數(shù)據(jù)的情況時(shí),象下面一樣設(shè)定。

          <components>
              <meta name="aaa">111</meta>
          </components>
          

          request的自動(dòng)綁定

          對(duì)于組件來(lái)說(shuō),也可以進(jìn)行HttpServletRequest的自動(dòng)綁定。為了實(shí)現(xiàn)這個(gè)目的,在組件中,定義了setRequest(HttpServletRequest request)方法。這樣的話,S2Container就自動(dòng)得設(shè)定了request。還有,需要象下面這樣在web.xml中進(jìn)行Filter的定義。

          <web-app>
          <filter>
          <filter-name>s2filter</filter-name>
          <filter-class>org.seasar.framework.container.filter.S2ContainerFilter</filter-class>
          </filter>

          <filter-mapping>
          <filter-name>s2filter</filter-name>
          <url-pattern>/*</url-pattern>
          </filter-mapping>
          </web-app>

          同樣地對(duì)HttpServletResponse、HttpSession、ServletContext也是只要定義了setter方法,就可以自動(dòng)綁定了。而且,使用了S2ContainerFilter的話,HttpServletRequest、HttpServletResponse、HttpSession、ServletContext就可以各自用request、response、session、application的名字來(lái)做為組件被自由訪問(wèn)了。

          組件的自動(dòng)注冊(cè)

          根據(jù)自動(dòng)綁定的原理,DI的設(shè)定幾乎可以做近乎全部的自動(dòng)化。 使用備注碼就有可能進(jìn)行更加細(xì)致的設(shè)定。 更進(jìn)一步、對(duì)組件的注冊(cè)也進(jìn)行自動(dòng)化的話,就可以稱為組件的自動(dòng)注冊(cè)機(jī)能了。

          org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister

          是從文件系統(tǒng)中將類檢索出來(lái)對(duì)組件進(jìn)行自動(dòng)注冊(cè)的組件。

          屬性說(shuō)明
          instanceDef在自動(dòng)注冊(cè)的組件中指定適用的InstanceDef。用XML指定的場(chǎng)合下,
          @org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST
          這樣來(lái)指定。
          autoBindingDef在自動(dòng)注冊(cè)的組件中指定適用的AutoBindingDef。用XML指定的場(chǎng)合下,
          @org.seasar.framework.container.assembler.AutoBindingDefFactory@NONE
          這樣來(lái)指定。
          autoNaming可以根據(jù)類名來(lái)自動(dòng)決定組件名的組件。需要實(shí)裝 org.seasar.framework.container.autoregister.AutoNaming interface。默認(rèn)狀態(tài)下,使用org.seasar.framework.container.autoregister.DefaultAutoNaming類的實(shí)例。

          方法說(shuō)明
          addClassPattern將想要自動(dòng)注冊(cè)的類模式注冊(cè)。最開始的一個(gè)參數(shù)是組件所在包的名字。子包也能被以回歸的方式進(jìn)行檢索。第二個(gè)參數(shù)是類的名字。可以使用正則表達(dá)式。也可以用“,”分隔做復(fù)數(shù)個(gè)設(shè)定。
          addIgnoreClassPattern將不想自動(dòng)注冊(cè)的類模式注冊(cè)。最開始的一個(gè)參數(shù)是組件所在包的名字。子包也能被以回歸的方式進(jìn)行檢索。第二個(gè)參數(shù)是類的名字。可以使用正則表達(dá)式。也可以用“,”分隔做復(fù)數(shù)個(gè)設(shè)定。
          org.seasar.framework.container.autoregister.JarComponentAutoRegister

          從Jar文件中檢索類自動(dòng)注冊(cè)組件的組件。

          屬性說(shuō)明
          jarFileNames指定設(shè)定對(duì)象的jar文件名。可以使用正則表達(dá)式。但是能包含后綴。指定復(fù)數(shù)個(gè)對(duì)象的場(chǎng)合下,用“,”做分割符。例如,myapp.*, yourapp.*這樣。
          referenceClass用這個(gè)屬性指定的類所屬的jar文件的父路徑為基礎(chǔ)路徑(例如,WEB-INF/lib)。默認(rèn)的是org.aopalliance.intercept.MethodInterceptor.class。
          instanceDef適用于自動(dòng)注冊(cè)的組件的InstanceDef的指定。在XML中如下,
          @org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST
          這樣指定。
          autoBindingDef適用于自動(dòng)注冊(cè)的組件的AutoBindingDef的指定。在XML中如下,
          @org.seasar.framework.container.assembler.AutoBindingDefFactory@NONE
          這樣指定。
          autoNaming根據(jù)類名自動(dòng)決定組件的名稱的組件。需要對(duì)org.seasar.framework.container.autoregister.AutoNaming interface 進(jìn)行實(shí)裝。默認(rèn)的情況下是org.seasar.framework.container.autoregister.DefaultAutoNaming類的實(shí)例。

          方法說(shuō)明
          addClassPattern將想要自動(dòng)注冊(cè)的類模式注冊(cè)。最開始的一個(gè)參數(shù)是組件所在包的名字。子包也能被以回歸的方式進(jìn)行檢索。第二個(gè)參數(shù)是類的名字。可以使用正則表達(dá)式。也可以用“,”分隔做復(fù)數(shù)個(gè)設(shè)定。
          addIgnoreClassPattern將不想自動(dòng)注冊(cè)的類模式注冊(cè)。最開始的一個(gè)參數(shù)是組件所在包的名字。子包也能被以回歸的方式進(jìn)行檢索。第二個(gè)參數(shù)是類的名字。可以使用正則表達(dá)式。也可以用“,”分隔做復(fù)數(shù)個(gè)設(shè)定。
          org.seasar.framework.container.autoregister.ComponentAutoRegister

          將類從文件系統(tǒng)或者Jar文件中檢索出來(lái)并將組件自動(dòng)注冊(cè)的組件。

          屬性說(shuō)明
          instanceDef適用于自動(dòng)注冊(cè)的組件的InstanceDef的指定。在XML中如下,@org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST這樣指定。
          autoBindingDef適用于自動(dòng)注冊(cè)的組件的AutoBindingDef的指定。在XML中如下,
          @org.seasar.framework.container.assembler.AutoBindingDefFactory@NONE
          這樣指定。
          autoNaming從類的名稱來(lái)自動(dòng)決定組件的名稱的組件。需要對(duì)org.seasar.framework.container.autoregister.AutoNaming instance進(jìn)行實(shí)裝。默認(rèn)的是 org.seasar.framework.container.autoregister.DefaultAutoNaming類的實(shí)例。

          方法說(shuō)明
          addReferenceClass以這個(gè)方法所指定的類所存在的路徑或者Jar文件為基點(diǎn)對(duì)類進(jìn)行檢索。
          addClassPattern將想要自動(dòng)注冊(cè)的類模式注冊(cè)。最開始的一個(gè)參數(shù)是組件所在包的名字。子包也能被以回歸的方式進(jìn)行檢索。第二個(gè)參數(shù)是類的名字。可以使用正則表達(dá)式。也可以用“,”分隔做復(fù)數(shù)個(gè)設(shè)定。
          addIgnoreClassPattern將不想 自動(dòng)注冊(cè)的類模式注冊(cè)。最開始的一個(gè)參數(shù)是組件所在包的名字。子包也能被以回歸的方式進(jìn)行檢索。第二個(gè)參數(shù)是類的名字。可以使用正則表達(dá)式。也可以用“,”分隔做復(fù)數(shù)個(gè)設(shè)定。

          AutoNaming

          根據(jù)AutoNaming來(lái)控制組件名稱。

          org.seasar.framework.container.autoregister.DefaultAutoNaming

          從類的完整合法名稱中將類的包的那部分名稱去掉,如果結(jié)尾是Impl或者Bean也要去掉,之后將開頭的字母變成小寫做為組件名稱來(lái)設(shè)定。 例如,aaa.HogeImpl類的情況下,組件的名稱就成了hoge。

          屬性說(shuō)明
          decapitalize組件名的開頭字母為小寫的情況下指定為true。默認(rèn)值是true。

          方法說(shuō)明
          setCustomizedName不依從于默認(rèn)的規(guī)則對(duì)類進(jìn)行注冊(cè)。第一個(gè)參數(shù)是類的完整合法名。第二個(gè)參數(shù)是組件的名稱。
          addIgnoreClassSuffix指定從類名的尾端消除的部分。注冊(cè)默認(rèn)值為Impl以及Bean。
          addReplaceRule根據(jù)正則表達(dá)式追加替換規(guī)則。第一個(gè)參數(shù)為正則表達(dá)式。第二個(gè)參數(shù)為向要替換的字符串。
          clearReplaceRule用setCustomizedName、addIgnoreClassSuffix、addReplaceRule將注冊(cè)的變換規(guī)則清零。作為默認(rèn)值被注冊(cè)的Impl和Bean也被清零。
          org.seasar.framework.container.autoregister.QualifiedAutoNaming

          將包的名字或者是一部分類的合法名做為組件名稱的設(shè)定。從類的完整合法名的最后把Impl或者Bean去掉,開頭字母小寫,分隔點(diǎn)后緊接著的字母變成大寫并取掉分隔點(diǎn),將這個(gè)新的單詞設(shè)定為組件的名稱。
          可以將包的開頭的不要的部分做消除指定。
          例如,aaa.bbb.ccc.ddd.HogeImpl類的情況下,將開頭的aaa.bbb做消除指定的情況下組件的名稱為,cccDddHogeになります。

          屬性說(shuō)明
          decapitalize組件名的開頭字母為小寫的情況下指定為true。默認(rèn)值是true。

          方法說(shuō)明
          setCustomizedName遵從默認(rèn)的規(guī)則來(lái)注冊(cè)類。第一個(gè)參數(shù)是類的完整合法名。 第二個(gè)參數(shù)是組件的名稱。
          addIgnorePackagePrefix從包名稱的開頭開始指定消除的部分。
          addIgnoreClassSuffix類名稱的最末尾開始指定消除的部分。默認(rèn)地將Impl和Bean注冊(cè)。
          addReplaceRule根據(jù)正則表達(dá)式追加替換規(guī)則。第一個(gè)參數(shù)為正則表達(dá)式。第二個(gè)參數(shù)是替換的新字符串。
          clearReplaceRule將setCustomizedName、 addIgnorePackagePrefix、 addIgnoreClassSuffix、 addReplaceRule注冊(cè)的替換規(guī)則清除。默認(rèn)注冊(cè)的Impl以及Bean也將被清除。
          <component
            class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
              <property name="autoNaming">
                  <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming">
                      <initMethod name="setCustomizedName">
                          <arg>"examples.di.impl.HogeImpl"</arg>
                          <arg>"hoge2"</arg>
                      </initMethod>
                  </component>
              </property>
              <initMethod name="addClassPattern">
                  <arg>"examples.di.impl"</arg>
                  <arg>".*Impl"</arg>
              </initMethod>
          </component>
          
          <component class="org.seasar.framework.container.autoregister.JarComponentAutoRegister">
              <property name="referenceClass">
                  @junit.framework.TestSuite@class
              </property>
              <property name="jarFileNames">"junit.*"</property>
              <initMethod name="addClassPattern">
                  <arg>"junit.framework"</arg>
                  <arg>"TestSuite"</arg>
              </initMethod>
          </component>
          
          <component class="org.seasar.framework.container.autoregister.ComponentAutoRegister">
              <initMethod name="addReferenceClass">
                  <arg>@aaa.bbb.ccc.ddd.HogeImpl@class</arg>
              </initMethod>
              <initMethod name="addClassPattern">
                  <arg>"aaa.bbb"</arg>
                  <arg>".*Impl"</arg>
              </initMethod>
          </component>
          

          AOP的自動(dòng)注冊(cè)

          根據(jù)組件的自動(dòng)注冊(cè)規(guī)則,組件的注冊(cè)可以做到自動(dòng)化。進(jìn)一步,AOP的注冊(cè)也可以做到自動(dòng)化,這就是AOP的自動(dòng)注冊(cè)機(jī)能。

          和組件的自動(dòng)注冊(cè)功能組和使用的場(chǎng)合下,必須在組件的自動(dòng)注冊(cè)設(shè)定之后,作AOP的自動(dòng)注冊(cè)的設(shè)定。對(duì)于適用于使用AOP的組件的記述,必須在AOP的自動(dòng)注冊(cè)設(shè)定之后進(jìn)行。

          <components>
              <!-- 1.組件的自動(dòng)注冊(cè) -->
              <component class="org.seasar.framework.container.autoregister.ComponentAutoRegister">
                  ...
              </component>
          
              <!-- 2.AOP的自動(dòng)注冊(cè) -->
              <component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
                  ...
              </component>
          
              <!-- 3.其它的組件 -->
              <component class="...">
                  ...
              </component>
              ...
          <components>
          
          org.seasar.framework.container.autoregister.AspectAutoRegister

          通過(guò)指定類名的模式來(lái)進(jìn)行AOP的自動(dòng)注冊(cè)的組件。

          屬性說(shuō)明
          interceptor指定interceptor。想要指定復(fù)數(shù)個(gè)interceptor的場(chǎng)合下,請(qǐng)使用InterceptorChain
          pointcut適于使用interceptor的方法用逗號(hào)分隔開進(jìn)行指定。不指定pointcut的情況下,實(shí)裝組件的interface的所有方法都做為interceptor的對(duì)象。對(duì)于方法名稱也可以使用正則表達(dá)式(JDK1.4のregex)來(lái)指定。

          方法說(shuō)明
          addClassPattern將想要自動(dòng)注冊(cè)的類的模式注冊(cè)。第一個(gè)參數(shù)是組件的包的名。子包也可以用回歸的方法檢索。第二個(gè)參數(shù)是類名。可以使用正則表達(dá)式。用“,”分隔可以做復(fù)數(shù)個(gè)記述。
          addIgnoreClassPattern將不想自動(dòng)注冊(cè)的類模式注冊(cè)。第一個(gè)參數(shù)是組件的包的名。子包也可以用回歸的方法檢索。第二個(gè)參數(shù)是類名。可以使用正則表達(dá)式。用“,”分隔可以做復(fù)數(shù)個(gè)記述。

          <include path="aop.dicon"/>
          ...
          <component
          class="org.seasar.framework.container.autoregister.AspectAutoRegister">
          <property name="interceptor">aop.traceInterceptor</property>
          <initMethod name="addClassPattern">
          <arg>"examples.di.impl"</arg>
          <arg>".*Impl"</arg>
          </initMethod>
          </component>
          org.seasar.framework.container.autoregister.InterfaceAspectAutoRegister

          針對(duì)某個(gè)interface的實(shí)裝類進(jìn)行AOP的自動(dòng)注冊(cè)的組件。

          屬性說(shuō)明
          interceptor指定interceptor。想要指定復(fù)數(shù)個(gè)interceptor的場(chǎng)合下,請(qǐng)使用InterceptorChain
          targetInterface針對(duì)某一指定的interface的實(shí)裝組件,使用AOP。
          <include path="aop.dicon"/>
          ...
          <component
          class="org.seasar.framework.container.autoregister.InterfaceAspectAutoRegister">
          <property name="interceptor">aop.traceInterceptor</property> <property name="targetInterface">@examples.Greeing@class</property>
          </component>

          META的自動(dòng)注冊(cè)

          META信息也可以自動(dòng)注冊(cè)。

          同組件的自動(dòng)注冊(cè)相組合使用的場(chǎng)合下,必須在組件的自動(dòng)注冊(cè)設(shè)定之后,做META的自動(dòng)注冊(cè)的設(shè)定記述。 調(diào)用META信息的組件必須在META自動(dòng)注冊(cè)的設(shè)定之后記述。

          <components>
              <!-- 1.組件的自動(dòng)注冊(cè) -->
              <component class="org.seasar.framework.container.autoregister.ComponentAutoRegister">
                  ...
              </component>
          
              <!-- 2.META的自動(dòng)注冊(cè) -->
              <component class="org.seasar.framework.container.autoregister.MetaAutoRegister">
                  ...
              </component>
          
              <!-- 3.其它的組件 -->
              <component class="...">
                  ...
              </component>
              ...
          <components>
          
          org.seasar.framework.container.autoregister.MetaAutoRegister

          通過(guò)指定類名的模式來(lái)做META自動(dòng)注冊(cè)的組件。
          被自動(dòng)注冊(cè)的META數(shù)據(jù),將做為在這個(gè)組件自身的定義中一個(gè)叫做autoRegister的META數(shù)據(jù)的子數(shù)據(jù)來(lái)記述。

          方法說(shuō)明
          addClassPattern將想要自動(dòng)注冊(cè)的類模式注冊(cè)。第一個(gè)參數(shù)是組件所在包的名字。子包也將被用回歸的方式所檢索。第二個(gè)參數(shù)是類名。可以使用正則表達(dá)式。用“,”做分隔符號(hào),可以做復(fù)數(shù)個(gè)記述。
          addIgnoreClassPattern將不想自動(dòng)注冊(cè)的類模式注冊(cè)。第一個(gè)參數(shù)是組件所在包的名字。子包也將被用回歸的方式所檢索。第二個(gè)參數(shù)是類名。可以使用正則表達(dá)式。用“,”做分隔符號(hào),可以做復(fù)數(shù)個(gè)記述。
          <component
            class="org.seasar.framework.container.autoregister.MetaAutoRegister">
              <meta name="autoRegister">
                  <meta name="hoge"</meta>
              </meta>
              <initMethod name="addClassPattern">
                  <arg>"examples.di.impl"</arg>
                  <arg>".*Impl"</arg>
              </initMethod>
          </component>
          

          本例中、叫做hoge的META數(shù)據(jù)自動(dòng)地注冊(cè)到其它的組件定義中。

          Hotswap

          一直以來(lái),更改了源代碼并重新編譯之后的場(chǎng)合,想要測(cè)試編譯后的機(jī)能,必須讓應(yīng)用程序(確切地說(shuō)是ClassLoader)再起動(dòng)。在應(yīng)用程序服務(wù)器上,進(jìn)行程序再起動(dòng)將非常花時(shí)間。 “真煩人”這樣想的人很多不是嗎。

          在Seasar2中,應(yīng)用程序在運(yùn)行中,即使類文件替換了,也可以即刻測(cè)試的Hotswap機(jī)能得以實(shí)現(xiàn)。這樣就讓我們從那種“心情煩躁”中解放出來(lái)了。無(wú)須花費(fèi)多余的時(shí)間使得出產(chǎn)率得以提高。這樣的好東西,不想試一試嗎?

          Greeting.java

          package examples.hotswap;
          
          public interface Greeting {
          
              String greet();
          }
          

          GreetingImpl.java

          package examples.hotswap.impl;
          
          import examples.hotswap.Greeting;
          
          public class GreetingImpl implements Greeting {
          
              public String greet() {
                  return "Hello";
              }
          }
          

          hotswap.dicon

          <components>
          <component class="examples.hotswap.impl.GreetingImpl"/>
          </components>

          到此為止,并沒有什么特別的變化。關(guān)鍵點(diǎn)從此開始。 使用s2container.dicon,切換成hotswap模式。

          s2container.dicon

          <components>
          <component
          class="org.seasar.framework.container.factory.S2ContainerFactory$DefaultProvider">
          <property name="hotswapMode">true</property>
          </component>
          </components>

          把s2container.dicon根據(jù)class path放到根路徑下的話,就能被自動(dòng)識(shí)別到。也可以使用S2ContainerFactory#configure()明確地指定。

          GreetingMain.dicon

          package examples.hotswap.main;
          
          import org.seasar.framework.container.S2Container;
          import org.seasar.framework.container.factory.S2ContainerFactory;
          
          import examples.hotswap.Greeting;
          
          public class GreetingMain {
          
              private static final String CONFIGURE_PATH =
                  "examples/hotswap/dicon/s2container.dicon";
          
              private static final String PATH =
                  "examples/hotswap/dicon/hotswap.dicon";
          
              public static void main(String[] args) throws Exception {
                  S2ContainerFactory.configure(CONFIGURE_PATH);
                  S2Container container = S2ContainerFactory.create(PATH);
                  System.out.println("hotswapMode:" + container.isHotswapMode());
                  container.init();
                  try {
                      Greeting greeting = (Greeting) container
                              .getComponent(Greeting.class);
                      System.out.println(greeting.greet());
                      System.out.println("Let's modify GreetingImpl, then press ENTER.");
                      System.in.read();
                      System.out.println("after modify");
                      System.out.println(greeting.greet());
                  } finally {
                      container.destroy();
                  }
              }
          }
          

          為了使用hotswap,有必要調(diào)用S2Container#init()。 執(zhí)行了的話"Hello"表示出來(lái)后,程序就停止了,所以將GreetingImpl#greet()修改并編譯使之表示"Hello2"。這之后,請(qǐng)將文字終端顯示窗口調(diào)成聚焦?fàn)顟B(tài)并按下ENTER鍵。雖然是用同一個(gè)instance也沒有關(guān)系,class文件被替換了的事實(shí)可以很容易的被測(cè)知。這個(gè)是實(shí)例模式為singleton的場(chǎng)合下的例子,實(shí)例模式為prototype的場(chǎng)合下,類將在調(diào)用S2Container#getComponent()的時(shí)刻被置換。

          執(zhí)行結(jié)果

          hotswapMode:true
          Hello
          Let's modify GreetingImpl, then press ENTER.
          
          after modify
          Hello2
          

          為了使用hotswap,組件提供了interface,組件的利用者方面,必須通過(guò)interface來(lái)利用組件。 實(shí)例模式為request、session的情況下,對(duì)于一個(gè)組件不能被其它的組件調(diào)用的場(chǎng)合來(lái)說(shuō),沒有interface也可以利用hotswap。

          S2Container標(biāo)簽參考

          DOCTYPE

          DOCTYPE要在XML聲明之后指定。請(qǐng)象下面那樣指定。

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.3//EN"
          "http://www.seasar.org/dtd/components23.dtd">
          <components>
              <component name="hello" class="examples.dicon.HelloConstructorInjection">
                  <arg>"Hello World!"</arg>
              </component>
          </components>
          

          components標(biāo)簽(必須)

          成為了根標(biāo)簽。

          namespace屬性(任意)

          可以指定命名空間。做為Java的標(biāo)識(shí)語(yǔ)來(lái)使用

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.3//EN"
          "http://www.seasar.org/dtd/components23.dtd">
          <components namespace="hoge">
              ...
          </components>
          

          include標(biāo)簽(任意)

          將被分割的S2Container的定義讀入的情況下使用。

          path屬性(必須)

          可以指定定義文件的路徑。相對(duì)于CLASSPATH所指定的路徑為根的絕對(duì)路徑。例如,WEB-INF/classes/aaa.dicon的情況下就指定為aaa.dicon 、WEB-INF/classes/aaa/bbb/ccc.dicon 的情況下就指定為 aaa/bbb/ccc.dicon 路徑分隔符在Windows下Unix下都是/。

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.3//EN"
          "http://www.seasar.org/dtd/components23.dtd">
          <components>
              <include path="aaa/bbb/ccc.dicon" />
          </components>
          

          component標(biāo)簽(任意)

          定義組件。

          class屬性(任意)

          指定類的完整合法名。在正文中,是用了OGNL式來(lái)指定組件的場(chǎng)合下,class的屬性可以被省略。使用OGNL式來(lái)指定類的屬性的時(shí)候,需要進(jìn)行類型檢查。

          name屬性(任意)

          指定名稱也可以。將做為Java的標(biāo)示語(yǔ)來(lái)使用。詳細(xì)情況請(qǐng)參照組件的取得

          instance屬性(任意)

          可以指定讓S2Container對(duì)組件的實(shí)例如進(jìn)行管理。可以指定singleton(默認(rèn))、prototype、outer、request、session幾種類型。更詳細(xì)的請(qǐng)參照實(shí)例管理

          autoBinding屬性(任意)

          S2Container可以指定如何解決組件之間的依存關(guān)系。有auto(默認(rèn))、constructor、property、none幾種類型。詳細(xì),請(qǐng)參照自動(dòng)綁定

          arg標(biāo)簽(任意)

          做為component標(biāo)簽的子標(biāo)簽來(lái)使用的場(chǎng)合下,就成了構(gòu)造函數(shù)的參數(shù)。根據(jù)記述的順序傳給構(gòu)造函數(shù)。 做為initMethod標(biāo)簽destroyMethod標(biāo)簽的子標(biāo)簽被使用的場(chǎng)合下,就成了方法函數(shù)的參數(shù)。按照記述的順序傳給方法函數(shù)。 做為參數(shù)被傳遞的實(shí)際值,要么在正文中使用OGNL式指定,要么在子標(biāo)簽中使用component標(biāo)簽指定。

          property標(biāo)簽(任意)

          做為component標(biāo)簽的子標(biāo)簽來(lái)使用。做為屬性變量被設(shè)定的實(shí)際值,要么在正文中使用OGNL式指定,要么在子標(biāo)簽中使用component標(biāo)簽指定。

          name屬性(必須)

          指定屬性變量名。

          bindingType屬性(任意)

          可以根據(jù)每一個(gè)屬性變量進(jìn)行細(xì)致的自動(dòng)綁定控制。must、should(默認(rèn))、may、none幾個(gè)類型可以用來(lái)指定。詳細(xì)請(qǐng)參照自動(dòng)綁定

          meta標(biāo)簽(任意)

          做為components標(biāo)簽component標(biāo)簽arg標(biāo)簽property標(biāo)簽的子標(biāo)簽來(lái)使用。META數(shù)據(jù)的值,要么在正文中使用OGNL式指定,要么在子標(biāo)簽中使用component標(biāo)簽指定。

          name屬性(任意)

          指定META名。

          initMethod標(biāo)簽(任意)

          做為component標(biāo)簽的子標(biāo)簽使用。參數(shù),在子標(biāo)簽中,使用arg標(biāo)簽指定。無(wú)須寫出name屬性,使用OGNL式也可以調(diào)用組件的方法。定義了initMethod標(biāo)簽的組件將做為表示組件自身#self、表示System.out#out、表示System.err#err等僅在initMethod標(biāo)簽內(nèi)部有效的對(duì)象來(lái)使用。

          name屬性(任意)

          指定方法名。

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.3//EN"
          "http://www.seasar.org/dtd/components23.dtd">
          <components>
              <component class="java.util.HashMap">
                  <initMethod name="put">
                      <arg>"aaa"</arg>
                      <arg>111</arg>
                  </initMethod>
                  <initMethod>#self.put("aaa", 111)</initMethod>
                  <initMethod>#out.println("Hello")</initMethod>
              </component>
          </components>
          

          destroyMethod標(biāo)簽(任意)

          和initMethod標(biāo)簽一樣。

          aspect標(biāo)簽(任意)

          將AOP組入到組件的定義中。詳細(xì)請(qǐng)參照S2AOP的aspect標(biāo)簽的說(shuō)明。

          interType標(biāo)簽(任意)

          象組件中組入interType。詳請(qǐng)請(qǐng)參照S2AOP的interType標(biāo)簽的說(shuō)明。

          description標(biāo)簽(任意)

          做為components標(biāo)簽component標(biāo)簽arg標(biāo)簽property標(biāo)簽的子標(biāo)簽可以使用description標(biāo)簽。可以自由地記述說(shuō)明。

          OGNL式

          在S2Container中,做為表達(dá)式語(yǔ)言可以利用

        1. char是象'a'一樣用'括起來(lái)。
        2. 數(shù)值就像123這樣直接記述。
        3. 倫理值就直接向true,false這樣記述。
        4. new java.util.Date(0)這樣可以用類的完整合法限定名來(lái)直接調(diào)用其構(gòu)造函數(shù)。
        5. @java.lang.Math@max(1, 2)這樣可以調(diào)用static方法的直接呼出結(jié)果。
        6. @java.lang.String@class這樣可以直接調(diào)用類。
        7. hoge.toString()這樣可以參照組件的方法調(diào)用結(jié)果。本例中,前提是在某個(gè)地方已經(jīng)定義了叫做hoge的組件。
        8. 詳細(xì)請(qǐng)參照OGNL指南

          S2Container備注碼參考

          在S2Container中,做為備注碼的實(shí)裝方法,準(zhǔn)備了Tiger備注碼?backport175備注碼?定數(shù)備注碼共3個(gè)種類。一般說(shuō)起備注碼的話,都是指從Java 5導(dǎo)入的Tiger備注碼,但是僅僅如此的話,JDK1.4的使用者將不可能利用這一個(gè)特性了。

          為了盡可能地讓更多的人樂(lè)意方便地使用備注碼,在JDK1.4中,可以使用Tiger風(fēng)格的備注碼(JSR-175) backport175備注碼,是利用public static final這樣的常量定義來(lái)完成備注碼功能的。

          Component備注碼

          backport175備注碼的利用方式如下。

          /**
           * @org.seasar.framework.container.annotation.backport175.Component(
           *      name = "xxx",
           *      instance = "prototype",
           *      autoBinding = "property")
           */
          public class Xxx {
              ...
          }
          

          常量備注碼的利用方式如下。

          public static final String COMPONENT =
            "name = xxx, instance = prototype, autoBinding = property";
          

          Binding備注碼

          backport175方式的備注碼如下。

          /**
          
           * @org.seasar.framework.container.annotation.backport175.Binding("aaa2")
           */
          public void setAaa(String aaa) {
              ...
          }
          
          /**
           * @org.seasar.framework.container.annotation.backport175.Binding(bindingType="none")
           */
          public void setBbb(String bbb) {
              ...
          }
          
          /**
           * @org.seasar.framework.container.annotation.backport175.Binding
           */
          public void setCcc(String ccc) {
              ...
          }
          

          常量備注碼要用屬性變量名_BINDING這樣來(lái)指定。

          public static final String aaa_BINDING = "aaa2";
          
          public static final String bbb_BINDING = "bindingType=none";
          
          public static final String ccc_BINDING = null;
          
          public void setAaa(Aaa aaa) {
              ...
          }
          
          public void setBbb(Bbb bbb) {
              ...
          }
          
          public void setCcc(Ccc ccc) {
              ...
          }
          

          Aspect備注碼

          aspect標(biāo)簽的替代使用方法是、Aspect備注碼。與aspect標(biāo)簽不同,因?yàn)榭梢远x復(fù)數(shù)個(gè)定義? 想要適用于復(fù)數(shù)個(gè)intercepter的情況下?請(qǐng)使用

          backport175方式的備注碼如下。

          /**
           * @org.seasar.framework.container.annotation.backport175.Aspect(
           *  "aop.traceInterceptor")
           */
          public class Xxx {
              ...
          }
          
          public class Xxx {
              ...
              /**
               * @org.seasar.framework.container.annotation.backport175.Aspect(
               *  "aop.traceInterceptor")
               */
              public void hoge() {
                  ...
              }
          }
          

          常量備注碼的形式如下。想要指定復(fù)數(shù)個(gè)pointcut的情況下,請(qǐng)象pointcut= get.*\nexecute.*這樣用\n做分隔。 不能使用\n之外的其它分隔文字。

          public static final String ASPECT =
              "value=aop.traceInterceptor, pointcut=getAaa";
          

          InterType備注碼

          backport175方式的備注碼如下。

          /**
           * @org.seasar.framework.container.annotation.backport175.InterType(
           *  {"aop.propertyInterType", "aop.someInterType"})
           */
          public class Xxx {
              ...
          }
          

          常量方式的備注碼如下。

          public static final String INTER_TYPE =
              "aop.propertyInterType, aop.someInterType";
          

          InitMethod備注碼

          initMethod標(biāo)簽的代替使用方法是InitMethod備注碼。 與initMethod標(biāo)簽不同,OGNL式的使用和參數(shù)的設(shè)定都不可以。

          Tiger方式的備注碼如下。

          public class Xxx {
              ...
              @InitMethod
              public void init() {
                  ...
              }
          }
          

          backport175方式的備注碼如下。

          public class Xxx {
              ...
              /**
               * @org.seasar.framework.container.annotation.backport175.InitMethod
               */
              public void init() {
                  ...
              }
          }
          

          常量方式的備注碼如下。想要指定復(fù)數(shù)個(gè)初始化方法的情況下,請(qǐng)用逗號(hào)(,)做分隔符。

          public static final String INIT_METHOD = "init";
          

          DestroyMethod備注碼

          destroyMethod標(biāo)簽的替代使用方式是DestroyMethod備注碼。 與destroyMethod標(biāo)簽不同,OGNL式的使用,參數(shù)的設(shè)定都不可以。

          Tiger方式的備注碼如下。

          public class Xxx {
              ...
              @DestroyMethod
              public void destroy() {
                  ...
              }
          }
          

          backport175方式的備注碼如下。

          public class Xxx {
              ...
              /**
               * @org.seasar.framework.container.annotation.backport175.DestroyMethod
               */
              public void destroy() {
                  ...
              }
          }
          

          常量備注碼如下。想要指定復(fù)數(shù)個(gè)初始化方法的情況下,請(qǐng)用逗號(hào)(,)做分隔符。

          public static final String DESTROY_METHOD = "destroy";
          


          posted on 2007-07-18 14:16 蠻哥♂楓 閱讀(24544) 評(píng)論(12)  編輯  收藏 所屬分類: JavaOpenSource

          FeedBack:
          # re: 小日本的開源框架 Seasar2
          2007-11-15 10:57 | lsd751@sohu.com
          挺好的。你自己從日文網(wǎng)站翻譯來(lái)的?  回復(fù)  更多評(píng)論
            
          # re: 小日本的開源框架 Seasar2
          2007-11-30 16:25 | yinzi
          不錯(cuò),仔細(xì)學(xué)習(xí)了一下.  回復(fù)  更多評(píng)論
            
          # re: 小日本的開源框架 Seasar2
          2007-12-13 20:37 |
          我最近在看它的文檔,是一個(gè)不錯(cuò)的東西,不過(guò)想s2dao之類的東西,最好還是別用,控制反轉(zhuǎn) 還是不錯(cuò),研究一下怎么用。
          jefnguo#gmail.com  回復(fù)  更多評(píng)論
            
          # re: 小日本的開源框架 Seasar2
          2007-12-20 17:20 | manu
          小日本就喜歡搞點(diǎn)小把戲
            回復(fù)  更多評(píng)論
            
          # re: 日本的開源框架 Seasar2
          2008-07-23 09:29 | hai
          內(nèi)容很不錯(cuò)。可是題目能不能不要“小”字?
          上班時(shí)候看真不方便。萬(wàn)一旁邊的同事懂點(diǎn)中國(guó)的事……

          ps: 如果是精神勝利法,沒有必要;如果是玩笑,也不應(yīng)該帶歧視性。  回復(fù)  更多評(píng)論
            
          # re: 小日本的開源框架 Seasar2
          2008-12-08 11:56 | 拜訪
          不過(guò),帶回家研究研究,謝謝你  回復(fù)  更多評(píng)論
            
          # re: 小日本的開源框架 Seasar2
          2008-12-16 20:32 | 過(guò)
          寫的很詳細(xì),我這兩天一直在看,期待關(guān)于seasar新的文章  回復(fù)  更多評(píng)論
            
          # re: 小日本的開源框架 Seasar2
          2008-12-25 22:50 | ln_xk
          我的項(xiàng)目一直在用它。不錯(cuò)的框架  回復(fù)  更多評(píng)論
            
          # re: 小日本的開源框架 Seasar2[未登錄]
          2010-01-29 14:45 | x
          寫的很詳細(xì)。多謝。。  回復(fù)  更多評(píng)論
            
          # re: 小日本的開源框架 Seasar2[未登錄]
          2011-12-26 11:52 | aaa
          @manu
          你有本事也搞一個(gè),人家能自己弄出來(lái)就很牛B了  回復(fù)  更多評(píng)論
            
          # re: 小日本的開源框架 Seasar2[未登錄]
          2012-02-27 10:27 | 小菜鳥
          嗯 很詳細(xì)  回復(fù)  更多評(píng)論
            
          # re: 小日本的開源框架 Seasar2[未登錄]
          2012-09-14 14:26 | zhang
          主站蜘蛛池模板: 磐安县| 阜南县| 漳浦县| 剑河县| 买车| 慈溪市| 沙坪坝区| 平塘县| 屏边| 花莲市| 托克逊县| 历史| 平顶山市| 大足县| 望江县| 河北省| 彭阳县| 平乐县| 闽清县| 吉木乃县| 巫溪县| 永宁县| 陆河县| 苏尼特右旗| 白城市| 腾冲县| 延庆县| 巴林左旗| 平武县| 永州市| 高雄县| 北川| 巴林右旗| 南汇区| 德兴市| 修水县| 通河县| 丰台区| 宾川县| 谷城县| 东城区|