山崎屋の技術メモ

IT業界で働く中でテクノロジーを愛するSIerのシステムエンジニア👨‍💻 | AndroidとWebアプリの二刀流🧙‍♂️ | コードの裏にあるストーリーを綴るブログ執筆者✍️ | 日々進化するデジタル世界で学び続ける探究者🚀 | #TechLover #CodeArtisan、気になること、メモしておきたいことを書いていきます。

【Spring Framework】component-scanのいろいろ①

はじめてのSpring Boot―「Spring Framework」で簡単Javaアプリ開発 (I・O BOOKS)

はじめてのSpring Boot―「Spring Framework」で簡単Javaアプリ開発 (I・O BOOKS)

  • 作者:槇 俊明
  • 出版社/メーカー: 工学社
  • 発売日: 2014/11/01
  • メディア: 単行本
以前の記事でSpringのアノテーションコンフィグについて記載した。

yyama1556.hateblo.jp

そこで登場した [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 名の一覧を表示する。

フォルダ構成。
f:id:yyama1556:20160810173038p:plain

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徹底入門 Spring FrameworkによるJavaアプリケーション開発

Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発

Spring Framework 5 プログラミング入門

Spring Framework 5 プログラミング入門

  • 作者:掌田 津耶乃
  • 出版社/メーカー: 秀和システム
  • 発売日: 2017/12/20
  • メディア: 単行本
Spring Data JPAプログラミング入門

Spring Data JPAプログラミング入門

  • 作者:溝口賢司
  • 出版社/メーカー: 秀和システム
  • 発売日: 2018/04/23
  • メディア: Kindle版