GreetingMain

Seasar 2.4.13からなぜか無くなってしまったGreetingMainというexample。
コマンドラインで簡単にDIやAOPの動作がみれて良かったんだけど、最近はDoltengのscaffoldが
チュートリアル代わりになっているのかな。

っていうわけで、GreetingMainをいろいろ触ってみるメモ。

まず環境は下記のとおり。

maven:2.0.8
Eclipse:eclipse-jee-europa-fall2-win32
Eclipseを動かしているJDK:jdk1.6.0_03
EclipseプロジェクトのJDK:jdk1.5.0_09
Seasar:2.4.22

まずは環境設定から。

mvn -Declipse.workspace=. eclipse:add-maven-repo

とやると、
.metadata\.plugins\org.eclipse.core.runtime\.settings\org.eclipse.jdt.core.prefs
ができて、中身は

#Sun Jan 27 21:30:12 JST 2008
org.eclipse.jdt.core.classpathVariable.M2_REPO=C\:\\Documents and Settings\\ユーザ名\\.m2\\repository

となる。

Eclipseを起動して、[Window] -> [Preferences...] -> [Java] -> [Build Path] -> [Classpath Variables] に、
M2_REPOがあるのを確認。

次にプロジェクトを作成

mvn archetype:create -DgroupId=examples.di -DartifactId=greetingmain

App.javaとAppTest.javaは削除し、pom.xmlを下記のようにする。
このあたり、Seasarのサンプルを適当にコピペしたのでツッコミ歓迎です(笑)。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>examples.di</groupId>
  <artifactId>greeringmain</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>greeringmain</name>
  <url>http://maven.apache.org</url>
  <repositories>
    <repository>
      <id>maven.seasar.org</id>
      <name>The Seasar Foundation Maven2 Repository</name>
      <url>http://maven.seasar.org/maven2</url>
    </repository>
  </repositories>
  <build>
    <sourceDirectory>src/main/java</sourceDirectory>
    <outputDirectory>target/classes</outputDirectory>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
    </resources>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <testOutputDirectory>target/test-classes</testOutputDirectory>
    <testResources>
      <testResource>
        <directory>src/test/resources</directory>
      </testResource>
    </testResources>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-source-plugin</artifactId>
        <executions>
          <execution>
            <id>source-jar</id>
            <phase>package</phase>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>org.seasar.container</groupId>
      <artifactId>s2-framework</artifactId>
      <version>2.4.22</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.seasar.container</groupId>
      <artifactId>s2-tiger</artifactId>
      <version>2.4.22</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.13</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>

greetingmainディレクトリに移動して、

mvn -DdownloadSources=true eclipse:eclipse

とやって、.projectと.classpathを自動生成させ、Eclipseからインポートする。

Eclipseからソースフォルダ src/main/resources を追加。(これmvnで自動でやってくんないのかな?)

で、コンポーネントのコードは、

package examples.di.service;

public interface GreetingService {
	String greet();
}
package examples.di.service.impl;

import examples.di.service.GreetingService;

public class GreetingServiceImpl implements GreetingService {

	public String greet() {
		return "Hello World!";
	}
}
package examples.di.service;

public interface GreetingClientService {
	void execute();
}
package examples.di.service.impl;

import examples.di.service.GreetingClientService;
import examples.di.service.GreetingService;

public class GreetingClientServiceImpl implements GreetingClientService {

	public GreetingService greetingService;

	public void execute() {
		System.out.println(greetingService.greet());
	}
}

で、Mainが、

package examples.di.main;

import org.seasar.framework.container.SingletonS2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;

import examples.di.service.GreetingClientService;

public class GreetingMain2 {

	private static final String PATH = "examples/di/dicon/GreetingMain2.dicon";

	public static void main(String[] args) {
		SingletonS2ContainerFactory.setConfigPath(PATH);
		SingletonS2ContainerFactory.init();
		GreetingClientService greetingClientService = SingletonS2Container.getComponent("greetingClientService");
		greetingClientService.execute();

	}
}

src/main/resources/examples/di/dicon/GreetingMain2.diconが、

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
	"http://www.seasar.org/dtd/components24.dtd">
<components>
	<component name="greetingService"
		class="examples.di.service.impl.GreetingServiceImpl"/>
	<component name="greetingClientService"
		class="examples.di.service.impl.GreetingClientServiceImpl">
		<property name="greetingService">greetingService</property>
	</component>
</components>

src/main/resources/log4j.propertiesが、

log4j.rootLogger=INFO,STDOUT
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.ImmediateFlush=true
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

log4j.category.org.seasar=DEBUG

で、実行結果が、

2008-01-28 00:46:26,375 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=examples/di/dicon/GreetingMain2.dicon
2008-01-28 00:46:26,578 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=examples/di/dicon/GreetingMain2.dicon
2008-01-28 00:46:26,625 [main] INFO org.seasar.framework.container.factory.SingletonS2ContainerFactory - Running on [ENV]product, [DEPLOY MODE]Normal Mode
Hello World!

AOP(traceInterceptor)を適用した場合は、src/main/resources/examples/di/dicon/GreetingMain3.diconが、

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
	"http://www.seasar.org/dtd/components24.dtd">
<components>
	<include path="aop.dicon"/>
	<component name="greetingService"
		class="examples.di.service.impl.GreetingServiceImpl">
		<aspect>aop.traceInterceptor</aspect>
	</component>
	<component name="greetingClientService"
		class="examples.di.service.impl.GreetingClientServiceImpl">
		<property name="greetingService">greetingService</property>
		<aspect>aop.traceInterceptor</aspect>
	</component>
</components>

で、Mainが、

package examples.di.main;

import org.seasar.framework.container.SingletonS2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;

import examples.di.service.GreetingClientService;

public class GreetingMain3 {

	private static final String PATH = "examples/di/dicon/GreetingMain3.dicon";

	public static void main(String[] args) {
		SingletonS2ContainerFactory.setConfigPath(PATH);
		SingletonS2ContainerFactory.init();
		GreetingClientService greetingClientService = SingletonS2Container.getComponent("greetingClientService");
		greetingClientService.execute();

	}
}

実行結果が、

2008-01-28 00:49:23,625 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=examples/di/dicon/GreetingMain3.dicon
2008-01-28 00:49:23,687 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=aop.dicon
2008-01-28 00:49:23,875 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=aop.dicon
2008-01-28 00:49:23,937 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=examples/di/dicon/GreetingMain3.dicon
2008-01-28 00:49:24,203 [main] INFO org.seasar.framework.container.factory.SingletonS2ContainerFactory - Running on [ENV]product, [DEPLOY MODE]Normal Mode
2008-01-28 00:49:24,203 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - BEGIN examples.di.service.impl.GreetingClientServiceImpl#execute()
2008-01-28 00:49:24,203 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - BEGIN examples.di.service.impl.GreetingServiceImpl#greet()
2008-01-28 00:49:24,203 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - END examples.di.service.impl.GreetingServiceImpl#greet() : Hello World!
Hello World!
2008-01-28 00:49:24,203 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - END examples.di.service.impl.GreetingClientServiceImpl#execute() : null

コンポーネントアスペクトの自動登録を行う場合は、src/main/resources/examples/di/dicon/GreetingMain4.diconが、

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
	"http://www.seasar.org/dtd/components24.dtd">
<components>
	<include path="aop.dicon"/>
	<component
		class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
		<initMethod name="addClassPattern">
			<arg>"examples.di.service.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.service.impl"</arg>
			<arg>".*Impl"</arg>
		</initMethod>
	</component>
</components>

で、Mainが、

package examples.di.main;

import org.seasar.framework.container.SingletonS2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;

import examples.di.service.GreetingClientService;

public class GreetingMain4 {

	private static final String PATH = "examples/di/dicon/GreetingMain4.dicon";

	public static void main(String[] args) {
		SingletonS2ContainerFactory.setConfigPath(PATH);
		SingletonS2ContainerFactory.init();
		GreetingClientService greetingClientService = SingletonS2Container.getComponent("greetingClientService");
		greetingClientService.execute();
	}
}

実行結果が、

2008-01-28 00:53:31,265 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=examples/di/dicon/GreetingMain4.dicon
2008-01-28 00:53:31,343 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=aop.dicon
2008-01-28 00:53:31,531 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=aop.dicon
2008-01-28 00:53:31,609 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=examples/di/dicon/GreetingMain4.dicon
2008-01-28 00:53:31,953 [main] INFO org.seasar.framework.container.factory.SingletonS2ContainerFactory - Running on [ENV]product, [DEPLOY MODE]Normal Mode
2008-01-28 00:53:31,953 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - BEGIN examples.di.service.impl.GreetingClientServiceImpl#execute()
2008-01-28 00:53:31,953 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - BEGIN examples.di.service.impl.GreetingServiceImpl#greet()
2008-01-28 00:53:31,953 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - END examples.di.service.impl.GreetingServiceImpl#greet() : Hello World!
Hello World!
2008-01-28 00:53:31,953 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - END examples.di.service.impl.GreetingClientServiceImpl#execute() : null

SMART deployの場合は、
2006-11-17 - 日記を参考にする。

src/main/resources/convention.diconが、

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
    "http://www.seasar.org/dtd/components24.dtd">
<components>
    <component class="org.seasar.framework.convention.impl.NamingConventionImpl">
        <initMethod name="addRootPackageName">
            <arg>"examples.di"</arg>
        </initMethod>
    </component>
</components>

src/main/resources/creator.diconが、

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
    "http://www.seasar.org/dtd/components24.dtd">
<components>
    <include path="convention.dicon"/>
    <include path="customizer.dicon"/>
    <component class="org.seasar.framework.container.creator.ServiceCreator"/>
</components>

src/main/resources/customizer.diconが、

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
    "http://www.seasar.org/dtd/components24.dtd">
<components>
<component name="serviceCustomizer" 
  class="org.seasar.framework.container.customizer.CustomizerChain">
</component>
</components>

src/main/resources/s2container.diconが、

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
    "http://www.seasar.org/dtd/components24.dtd">
<components>
    <include path="warmdeploy.dicon"/>
</components>

src/main/resources/app.diconが、

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

Mainが、

package examples.di.main;

import org.seasar.framework.container.SingletonS2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;

import examples.di.service.GreetingClientService;

public class GreetingMain5 {

	public static void main(String[] args) {
		SingletonS2ContainerFactory.init();
		GreetingClientService greetingClientService = SingletonS2Container.getComponent("greetingClientService");
		greetingClientService.execute();
	}
}

実行結果が、

2008-01-28 01:05:10,218 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=warmdeploy.dicon
2008-01-28 01:05:10,234 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=convention.dicon
2008-01-28 01:05:10,421 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=convention.dicon
2008-01-28 01:05:10,421 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=customizer.dicon
2008-01-28 01:05:10,468 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=customizer.dicon
2008-01-28 01:05:10,468 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=creator.dicon
2008-01-28 01:05:10,484 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=creator.dicon
2008-01-28 01:05:10,500 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=warmdeploy.dicon
2008-01-28 01:05:10,562 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=app.dicon
2008-01-28 01:05:10,593 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=app.dicon
2008-01-28 01:05:10,593 [main] INFO org.seasar.framework.container.factory.SingletonS2ContainerFactory - Running on [ENV]product, [DEPLOY MODE]Warm Deploy
2008-01-28 01:05:10,609 [main] DEBUG org.seasar.framework.container.util.S2ContainerUtil - クラス(examples.di.service.impl.GreetingClientServiceImpl[greetingClientService])のコンポーネント定義を登録します
2008-01-28 01:05:10,609 [main] DEBUG org.seasar.framework.container.util.S2ContainerUtil - クラス(examples.di.service.impl.GreetingServiceImpl[greetingService])のコンポーネント定義を登録します
Hello World!

次に、トレースインターセプタを適用する。

src/main/resources/app.diconが、

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
	"http://www.seasar.org/dtd/components24.dtd">
<components>
<include path="aop.dicon"/>
</components>

src/main/resources/customizer.diconが、

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
    "http://www.seasar.org/dtd/components24.dtd">
<components>
<include path="default-customizer.dicon"/>
<component name="serviceCustomizer" 
  class="org.seasar.framework.container.customizer.CustomizerChain">
    <initMethod name="addCustomizer">
      <arg>traceCustomizer</arg>
    </initMethod>
</component>
</components>

実行結果が、

2008-01-28 01:07:08,906 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=warmdeploy.dicon
2008-01-28 01:07:08,921 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=convention.dicon
2008-01-28 01:07:09,109 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=convention.dicon
2008-01-28 01:07:09,109 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=customizer.dicon
2008-01-28 01:07:09,171 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=default-customizer.dicon
2008-01-28 01:07:09,203 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=std-customizer.dicon
2008-01-28 01:07:09,296 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=std-customizer.dicon
2008-01-28 01:07:09,312 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=default-customizer.dicon
2008-01-28 01:07:09,312 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=customizer.dicon
2008-01-28 01:07:09,312 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=creator.dicon
2008-01-28 01:07:09,328 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=creator.dicon
2008-01-28 01:07:09,343 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=warmdeploy.dicon
2008-01-28 01:07:09,390 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=app.dicon
2008-01-28 01:07:09,390 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成します。path=aop.dicon
2008-01-28 01:07:09,453 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=aop.dicon
2008-01-28 01:07:09,453 [main] DEBUG org.seasar.framework.container.factory.S2ContainerFactory - S2Containerを作成しました。path=app.dicon
2008-01-28 01:07:09,531 [main] INFO org.seasar.framework.container.factory.SingletonS2ContainerFactory - Running on [ENV]product, [DEPLOY MODE]Warm Deploy
2008-01-28 01:07:09,531 [main] DEBUG org.seasar.framework.container.util.S2ContainerUtil - クラス(examples.di.service.impl.GreetingClientServiceImpl[greetingClientService])のコンポーネント定義を登録します
2008-01-28 01:07:09,734 [main] DEBUG org.seasar.framework.container.util.S2ContainerUtil - クラス(examples.di.service.impl.GreetingServiceImpl[greetingService])のコンポーネント定義を登録します
2008-01-28 01:07:09,750 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - BEGIN examples.di.service.impl.GreetingClientServiceImpl#execute()
2008-01-28 01:07:09,750 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - BEGIN examples.di.service.impl.GreetingServiceImpl#greet()
2008-01-28 01:07:09,750 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - END examples.di.service.impl.GreetingServiceImpl#greet() : Hello World!
Hello World!
2008-01-28 01:07:09,750 [main] DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor - END examples.di.service.impl.GreetingClientServiceImpl#execute() : null

うーん、SMART deployになってdiconファイルが増えているので、結構ややこしいですね。

id:koichikさんが言っている

convention.dicon・creator.dicon・customizer.dicon の三点セットがちょっと鬱陶しいでしょうか?

でもでも,これらは通常 Seasar2.4 の配布ファイル中に含まれている (resouces ディレクトリにあります) ものをコピーすれば,ルートパッケージ以外はほとんど手を加える必要がありません.

Dolteng を使えばそのコピーさえ不要になります.

Seasar2.3 では AutoRegister により一つ一つのコンポーネントを設定する手間を省きました.

Seasar2.4 では SMART deploy により AutoRegister を設定する手間も省きました.

残るのはルートパッケージ名の定義とカスタマイザの微調整くらい.

着実に進歩していることを実感して頂けるかと思います.

と,おいらが偉そうに書いてますが,これらを考案したのは当然ひがさん.

さすがです♪

は、まあわかるのですが、ある程度スキルがある人でないと、敷居は高いかな。頭がこんがらがりそう。

まあ、diconをいじるのはスキルのあるアーキテクトであって、開発担当者はいじらないだろうしね。

Seasar - DI Container with AOP -をみて勉強しないと。

あと、2006-11-18 - 日記にはHOT deployの話もあります。

以上。