Spring 3.0 : DI についてみてみる

最初にSpringをつかったときは、Bean定義を全部XMLファイルに書かなければいけなくて、げんなりしました。その後、名前で自動的にBeanをコンテナに登録してくれるSeasar2をつかって、ああもうSpringいらない、と思ったものです。で、久しぶりにSpring 3.0 をみてみると、アノテーションやなんやらで、やっぱりほぼ設定レス。applicationContextにBean定義を直接書くことはほとんどないです。理解しなくても、なんとなく動く。が、それは気持ち悪いので、今日はDIの、自動登録部分あたりのリファレンス読みます。

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/

XMLファイルによる設定が基本なのは変わらないものの、他に2つの設定方法が追加されています。

今日は、アノテーションベースの方、でまずはクラスの自動検出の方をみていきます。

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-classpath-scanning

  • クラスパスからBeanを自動で検出してコンテナに登録するようにするには、以下の設定を追加する。
<?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-3.0.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:component-scan base-package="org.example"/>

</beans>
  • component-scan を設定すると、autowired設定も自動的に設定される。
  • で検出してほしいクラスに、@Component などのアノテーションをつける
  • @Repository, @Service, @Controllerの各アノテーションは@Componentをある特定の用途に特化させてクラス。だから、このannotationがついているクラスもコンテナ管理になる。
  • デフォルトでは、以下のクラスが自動検出対象
    • @Component @Repository @Service @Controller でアノテートされているクラス
    • それ自身が@Componentでアノテートされているカスタムアノテーションがついているクラス
  • Filterを追加することで、検出方法を制御することもてきる
    • component-scan要素の子要素にinclude-filter/exclude-filterを追加すればOK
    • filterのタイプにはannotation/assignable/aspectj/regex/customがある
    • Rooでプロジェクト作成すると、src/main/resources/META-INF/applicationContext.xmlの設定はデフォルトこんな感じ。名前に_Roo_がはいっているクラスと@Controllerは除外される。
	<context:component-scan base-package="com.example">
		<context:exclude-filter expression=".*_Roo_.*" type="regex"/>
		<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
	</context:component-scan>
  • @Beanアノテーションをつかえば、Beanのスコープなどの設定もアノテーションで行うことができる
  • 明示的にBeanの名前を指定する場合は@Service("mySerivice")みたいにすればおけ。
  • @Scopeアノテーションを使用すれば、スコープを変更することもできる。デフォルトはSingleton
  • @Qualifierアノテーションについては、後でみる。
  • これで@Autowiredなどを利用すれば定義されているBeanが自動で注入される。


Controllerクラスはweb層でインスタンス化されるからここでは除外するらしいです。でもWEBアプリとして起動するとここでインスタンス化されたサービスクラスがちゃんと注入されてるんですよね。ということは、コンテナ(?)がなんか階層化されてたりしてるってこと??うーーん、わからなくなってきたが、WEB MVC部分のコンテナ構造については後回しにして、次は3.9 の自動検出して生成したインスタンスたちを注入する設定をアノテーションでどう書くのよ、ということに迫りたいと思います。