3.10. Classpath scanning and managed components
3.10.1 @Component and further stereotype annotations
クラスアノテーションとしてこれらを付与するとコンポーネントとして登録される。おすすめはちゃんと責務ごとに@Controller/@Service/@Repositoryをつけ分けること。AspectJでアノテーションを条件にポイントカットしてうまくやれたりするので、そのほうが良い。
ちなみに現時点では@Repositoryが付いていると勝手に例外変換してくれる。その他のアノテーションはSpringの将来のリリースで追加機能がサポートされるかも
3.10.2 Automatically detecting classes and registering bean definitions
ステレオタイプアノテーションをつけたクラスは、勝手にSpringのBeanとして登録される。これを有効にするにはXMLにcomonent-scanをつける。検索対象パッケージ(指定は以下のパッケージが再帰的に検索される)は、カンマ区切りで複数定義できる。
<?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>
をいれると、内部的にはAutowiredAnnotationBeanPostProcessorとCommonAnnotationBeanPostProcessorが登録される。
3.10.3 Using filters to customize scanning
デフォルトでは、@Component, @Repository, @Service, @Controller,及び@Componentをアノテートしたカスタムアノテーションが付けられたクラスが登録される。だがしかし、この振る舞いはcustom filtersによって変更できる。
<beans>
<context:component-scan base-package="org.example">
<context:include-filter type="regex" expression=".*Stub.*Repository"/>
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
</beans>フィルタの種類:Table 3.5. Filter Types
Filter Type Example Expression Description annotation org.example.SomeAnnotation アノテーション指定 assignable org.example.SomeClass 実装・継承するインタフェース(クラス)を指定 aspectj org.example..*Service+ AspectJ type expressionでマッチしたコンポーネント regex org\.example\.Default.* 正規表現でクラス名がマッチしたコンポーネント custom org.example.MyTypeFilter org.springframework.core.type.TypeFilterを実装したカスタム実装
3.10.4 Defining bean metadata within components
@Componentしたクラスに対して、(後述するSpring JavaConfigのように)@Beanなどを定義できます。(@Configurationしたクラスみたいに)
@Component
public class FactoryMethodComponent {
@Bean @Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
public void doWork() {
// Component method implementation omitted
}
}ちなみに@Componentに@Bean付けた場合は、@Configurationに@Bean付けた場合と違いCGLIBでエンハンスされないらしい。よくわからんが・・・
3.10.5 Naming autodetected components
Beanの名前は、BeanNameGeneratorによって決定される。デフォルトではSpringのステレオタイプアノテーションはname属性を持っており、これによって決定されます。JSR 330's @Namedも使えます。ちなみにnameの値を指定しなかった場合は自動的にクラス名の先頭1文字目を小文字にした値になります。
デフォルトの命名規則を変えるには
みたいな感じ。
<beans>
<context:component-scan base-package="org.example" name-generator="org.example.MyNameGenerator" />
</beans>
3.10.6 Providing a scope for autodetected components
アノテーションでスコープを指定できます。
ちなみにScopeMetadataResolverを実装してスコープに関する処理に介入できます。
@Scope("prototype")
@Repository
public class MovieFinderImpl implements MovieFinder {
<beans>
<context:component-scan base-package="org.example"
scope-resolver="org.example.MyScopeResolver" />
</beans>またscoped-proxyの設定もできます。設定値はno,interface,targetClassの3つ
<beans>
<context:component-scan base-package="org.example"
scoped-proxy="interfaces" />
</beans>
3.10.7 Providing qualifier metadata with annotations
@Qualifierや@Qualifierを使ったカスタムアノテーションをBeanにアノテーションすることでQualifier指定できます。