最近、いろいろテストやチュートリアルの学習用にsimple spring web maven
をベースに独自のパッケージ構成や、フォルダ構成にした上で使う場合が多いのですが、さすがに毎回の作業は手間です。
そこで、雛形を作成するようなものはないかと調べてみると、Archetype
を独自に作成することが出来るらしい。
・・というわけで、いろいろやってみたことのメモです(あくまで、自分用のメモです)。
- IDEは、STS3.9.6
- 作業したMavenのバージョンは3.5.4(Mavenのインストール等は割愛)。
web.xml
の<display-name></display-name>
にartifactId
を挿入する。- パッケージの構成を、
groupId.artifactId
みたいにする。 src/resources
配下に、artifactId
を冠するファイルを配置したい。- etc..
空のArchetypeの作成
cd /work
mvn archetype:generate -B -DarchetypeArtifactId=maven-archetype-archetype \
-DgroupId=com.example \
-DartifactId=spring-web-custom \
-Dversion=1.0-SNAPSHOT
-
-DarchetypeArtifactId=maven-archetype-archetype
:Mavenが提供している新しいカスタムarchetypeを作成するためのArchetype。 -
出来上がったディレクトリ、
spring-web-custom
に移動し、mvn eclipse:eclipse
コマンドを発行して、eclipseで使えるようにする。
cd spring-web-custom
mvn eclipse:eclipse
- Eclipseにインポートする。
Eclipse上での作業
インポート直後のフォルダ構成
- 雛形は、
archetype-resources/
以下に作っていく。
`-- spring-web-custom
|-- src/main/resources/
| |-- archetype-resources/
| | |-- src/
| | | |-- main/
| | | | `-- java/
| | | | `-- App.java
| | | `-- test/
| | | `-- java/
| | | `-- AppTest.java
| | `-- pom.xml
| `-- META-INF/
| `-- maven/
| `-- archetype.xml
|-- target/
|-- .classpath
|-- .project
`-- pom.xml
最終的にプロジェクトに展開した際のフォルダ構成を、このようにしたい。
`-- someapplication
|-- src/main/java/
| `-- com.example.someapplication/
| |-- app/
| | `-- HelloController.java
| |-- domain/
| | |-- model/
| | |-- repository/
| | `-- service/
| `-- App.java
|-- src/test/java/
| `-- com.example.someapplication/
| `-- AppTest.java
|-- src/main/resources/
| `-- META-INF/
| `-- spring/
| |-- someapplication-domain.xml
| |-- applicationContext.xml
| |-- application.properties
| `-- spring-mvc.xml
|-- src/
| `-- main/
| `-- webapp/
| `-- WEB-INF/
| |-- view/
| | `-- showMessage.jsp
| `-- web.xml
|-- target/
|-- .classpath
|-- .project
`-- pom.xml
雛形にファイルやディレクトリを配置していく。pom.xml
は、archetype-resources/
直下のpomを編集する。
`-- spring-web-custom
|-- src/main/resources/
| |-- archetype-resources/
| | |-- src/
| | | |-- main/
| | | | |-- java/
| | | | | |-- app/
| | | | | | `--HelloController.java
| | | | | |-- domain/
| | | | | | |-- model/
| | | | | | |-- repository/
| | | | | | `-- service/
| | | | | `-- App.java
| | | | |-- resources/
| | | | | `-- META-INF/
| | | | | `-- spring/
| | | | | |-- __projectName__-domain.xml
| | | | | |-- applicationContext.xml
| | | | | |-- application.properties
| | | | | `-- spring-mvc.xml
| | | | `-- webapp/
| | | | `-- WEB-INF/
| | | | |-- view/
| | | | | `-- showMessage.jsp
| | | | `-- web.xml
| | | `-- test/
| | | `-- java/
| | | `-- AppTest.java
| | `-- pom.xml
| `-- META-INF/
| `-- maven/
| `-- archetype.xml
|-- target/
|-- .classpath
|-- .project
`-- pom.xml
最終的に出力されるパッケージのフォルダ構成と、雛形で作成しているフォルダ構成の違いに注意。
その辺は、後でarchetype.xml
(実際にはarchetype-metadata.xml
)で設定をする。
archetype-metadata.xmlの編集
雛形を作成した当初は、archetype.xml
となっているが、名前をarchetype-metadata.xml
に変えて、内容を全て消去し、次のようにする。
<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor
xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd"
name="basic">
<requiredProperties>
<requiredProperty key="projectName">
<defaultValue>${artifactId}</defaultValue>
</requiredProperty>
<requiredProperty key="package">
<defaultValue>${groupId}.${artifactId}</defaultValue>
</requiredProperty>
<requiredProperty key="groupIdToPath">
<defaultValue>com/example</defaultValue>
</requiredProperty>
</requiredProperties>
<fileSets>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/test/java</directory>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/resources/META-INF/spring</directory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/resources/META-INF/mybatis</directory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/resources/META-INF</directory>
<includes>
<include>*.xml</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/java/__groupIdToPath__/__artifactId__/domain/model</directory>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/java/__groupIdToPath__/__artifactId__/domain/repository</directory>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/java/__groupIdToPath__/__artifactId__/domain/service</directory>
</fileSet>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/webapp/WEB-INF</directory>
<includes>
<include>*.xml</include>
</includes>
</fileSet>
<fileSet filtered="false" encoding="UTF-8">
<directory>src/main/webapp/WEB-INF</directory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
</fileSets>
</archetype-descriptor>
<requiredProperties> の設定
archetype-metadata.xml
にプロパティを設定する。
- プロパティに値を設定しておくことで、ファイル名や、ファイル中のテキストに値を展開できる。
- この例では、projectName、packages、groupIdToPathに値を設定しています。
例えば、ファイル名に__projectName__-domain.xml
としておけば、最終展開されたときに、someapplication-domain.xml
と展開される。
また、ファイル中の${projectName}
とされている部分も、someapplication
と展開される。例として、あるBean定義ファイルの中の:
<import resource="classpath:/META-INF/spring/${artifactId}-domain.xml" />
は、
<import resource="classpath:/META-INF/spring/someapplication-domain.xml" />
という形で展開される。
上記プロパティの中で、groupIdToPath は、本来であれば${groupId.replaceAll("\\.", "/")} とすればいいのかもしれないが、バグが有るために意図通りに処理されない。(参照 Required property default value incorrect when using system property)このリンクには、修正パッチがある(時間の都合で試していない)。 |
fileSetsの設定
<fileSets>
<!-- (1) -->
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/test/java</directory>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/resources/META-INF/spring</directory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/resources/META-INF</directory>
<includes>
<include>*.xml</include>
</includes>
</fileSet>
<!-- (2) -->
<!-- (3) -->
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/java/__groupIdToPath__/__artifactId__/domain/model</directory>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/java/__groupIdToPath__/__artifactId__/domain/repository</directory>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/java/__groupIdToPath__/__artifactId__/domain/service</directory>
</fileSet>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/webapp/WEB-INF</directory>
<includes>
<include>*.xml</include>
</includes>
</fileSet>
<fileSet filtered="false" encoding="UTF-8">
<directory>src/main/webapp/WEB-INF</directory>
<includes>
<!-- (4) -->
<include>**/*</include>
</includes>
</fileSet>
</fileSets>
番号 | 説明 |
---|---|
(1) | filtered 、packaged 、encoding の各属性がある。 |
(2) | プロパティのキーを__ (アンダーバー2つ)で囲むことで、値に変換される。(${artifactId} は、その文字のままになる) |
(3) | 何も指定していないと、空のディレクトリはコピーされないが、このように明示しておくことで、空のディレクトリもコピーされる。 |
(4) | 指定されているディレクトリ内の、全てのディレクトリの配下にある全てのディレクトリ、ファイル。 |
各属性について
属性 | タイプ | 説明 |
---|---|---|
filtered |
boolean |
true とすることで、ファイルセットをVelocity テンプレートとしてフィルタリングして、プロパティの値に置き換えられます。false の場合は、何も変更が加えられず、ただ単にコピーされます。デフォルトは true |
packaged |
boolean |
true とすることで、選択されたファイルは${package} プロパティで表されるディレクトリ構造内にコピーされます。今回の例の場合、パッケージ名はcom.example.someapplication なので、ディレクトリ、com/example/sommeaplication/ (存在しない場合は、ディレクトリが作成される)にコピーされる。デフォルトは false |
encoding |
String |
内容をフィルタリングする際のエンコーディング |
雛形に配置している.java
ファイルの内容
App.java
package ${package};
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
- この
${package}
は、com.example.someapplication
と展開される。
実際の雛形では、src/main/java/App.java
となっているが、${package}
で指定して、<fileset>
のfiltered="true"
とすることで、プロジェクトに展開したときに、src/main/java/com/example/someapplication/App.java
に配置される。
HelloController.java
package ${package}.app;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("")
public String hello(
@AuthenticationPrincipal UserDetails userdetails,
Model model) {
model.addAttribute("message", userdetails.toString());
return "showMessage";
}
}
HelloController.java
は、${package}.app
とすることで、相対的なパッケージ名になるようにしている。
ローカルリポジトリにインストール
mvn clean;mvn package;mvn install
作成したArchetypeをベースにプロジェクト作成
次のようにして、作成した自前の ArcheType をひな形にしてプロジェクトを作成します。
mvn archetype:generate -DarchetypeGroupId=com.example \
-DarchetypeArtifactId=spring-web-custom \
-DarchetypeVersion=0.0.1 \
-DgroupId=com.example \
-DartifactId=demospring
Eclipse にインポートする場合は、先程のコマンドで作成されたディレクトリ (例: demospring/) に移動して、
mvn eclipse:eclipse
を実行します。
PowerShell を使用されている場合は要注意!!
ただし、もし Microsoft の PowerShell を使用している場合は、プロジェクト作成時のコマンドを次のように各オプションを ダブルクォーテーション ("
) で囲まないと、作成に失敗します。
mvn archetype:generate -DarchetypeGroupId=com.example \
"-DarchetypeArtifactId=spring-web-custom" \
"-DarchetypeVersion=0.0.1" \
"-DgroupId=com.example" \
"-DartifactId=demospring"
0件のコメント