はじめてのSpring Boot―「Spring Framework」で簡単Javaアプリ開発 (I・O BOOKS)
- 作者:槇 俊明
- 出版社/メーカー: 工学社
- 発売日: 2014/11/01
- メディア: 単行本
そこで登場した [component-scan] について、もう少し掘り下げてメモしておく。
以下のタグ/属性について記載する。
・context:component-scan タグの use-default-filters 属性
・context:include-filter タグ
・context:exclude-filter タグ
環境は Windows7、JDK1.8、Spring 4.2.3。でも Linux でも Mac でも同じ話。 Java の理念は「Write once, run anywhere」(一度書いたらどこでも実行)。
基本サンプル
Main クラスの main メソッドで、Spring コンテキストに登録されている bean 名の一覧を表示する。
フォルダ構成。
applicationContext.xml。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="org.yyama.hoge" /> </beans>
[org.yyama.hoge] パッケージ以下で @Component などのアノテーションが付与されたクラスをコンテナに登録するように設定している。
Main クラス。
package org.yyama; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String... args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); for (String string : ctx.getBeanDefinitionNames()) { if (string.indexOf("spring") == -1) System.out.println(string); } ctx.close(); } }
ApplicationContext の getBeanDefinitionNames() メソッドを使用して、登録されている bean 名の一覧を取得している。ただし "spring" という文字列を含む bean は Spring がデフォルトで登録する bean なので表示から除外している。
Fuga クラス。
package org.yyama.hoge; import org.springframework.stereotype.Component; @Component public class Fuga { }
クラスが Spring にどのように登録されるかを調査するため、@Component アノテーションを付けてクラス宣言しているだけ。
Piyo クラス。
package org.yyama.hoge; import org.springframework.stereotype.Service; @Service public class Piyo { }
こちらのクラスは @Service アノテーションを付けている。
本題とは関係ないが、一応、pom.xml。
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.springframework.samples</groupId> <artifactId>Sample</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <!-- Generic properties --> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- Spring --> <spring-framework.version>4.3.2.RELEASE</spring-framework.version> </properties> <dependencies> <!-- Spring and Transactions --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring-framework.version}</version> </dependency> </dependencies> </project>
実行してみると。
fuga piyo
[org.yyama.hoge] パッケージ配下で @Component アノテーションが付与されている Fuga クラスと @Service アノテーションを付与している Piyo クラスが Spring に登録されていることがわかる。出力の "fuga" は先頭のFが小文字となっているが、これはクラス名の先頭 1 文字を小文字にした文字列がデフォルトで bean 名として Spring に登録されるから( "piyo" も同じ )。
[use-default-filters="false"] を使ってみる
applicationContext.xml の component-scan に [use-default-filters="false"] を付与してみる。ちなみに [use-default-filters] はデフォルトで "true" である。
applicationContext.xml。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="org.yyama.hoge" use-default-filters="false" /> </beans>
実行結果。
Fuga クラスも Piyo クラスも登録されていない。
デフォルトでもある [use-default-filters="true"] を指定すると base-package に指定したパッケージ配下の @Component/@Repository/@Service/@Controller が指定されたクラスをコンテナに登録する。一方、"false" とするとそれらを無効にする。すなわち何も登録しないということになる。したがって、[use-default-filters="false"] を指定した場合は、[include-filter] を使用して明示的に登録するクラスを指定しなければいけない。
長くなりそうなので、記事を分ける。
続きはこちら 【Spring Framework】component-scanのいろいろ②
余談だが @Component と @Service はソースレベルで全く同じもの。こちらの記事で紹介している。
【Spring】@Autowired と @Component を使用した DI の基本 - 山崎屋の技術メモ
Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発
- 作者:株式会社NTTデータ
- 出版社/メーカー: 翔泳社
- 発売日: 2016/07/21
- メディア: 大型本
- 作者:掌田 津耶乃
- 出版社/メーカー: 秀和システム
- 発売日: 2017/12/20
- メディア: 単行本
- 作者:溝口賢司
- 出版社/メーカー: 秀和システム
- 発売日: 2018/04/23
- メディア: Kindle版