1.10。クラスパスのスキャンと管理対象コンポーネント
1.10.1。@Componentステレオタイプの注釈とより
@Repository
注釈リポジトリを達成することであるマーキング又は構造的役割の任意のタイプ(データアクセスオブジェクトまたはDAOと呼ばれます)。タグの使用は、自動的に異常に翻訳されています。
春はさらにステレオタイプを提供@Component
注釈を:、@Service
と@Controller
。任意のタイプの構造は、一般的な@Component春管理コンポーネントです。リポジトリ@、サービスと@Controller @より具体的な@Componentユースケース(それぞれ、持続性、サービスおよびプレゼンテーション層)に特化されています。そのため、あなたは@Component注釈のコンポーネントクラスを使用することができ、しかし、リポジトリ@により、サービスまたは@Controllerがそれらに注釈を付ける@、あなたのクラスは、より良いツールで治療に適し、または側面を関連付けます。例えば、これらのステレオタイプは、ターゲットのための理想的なエントリポイントのためのより適切なコメント。リポジトリ@、サービスおよび@Controller @ Springフレームワークの将来のバージョンでも、他の意味を含めることができます。あなたは、サービス層に@Componentまたはサービス@を使用することを選択したのであれば、サービス@それは明らかに良い選択です。また、以前のように、リポジトリ番号@既に自動変換層の持続的な異常でサポートされます。
ノート組成物は、カスタマイズを可能にするメタデータの再ステートメント注釈のプロパティから選択することができます。あなたはメタアノテーションの属性のサブセットを開きたい場合は、この機能は特に便利です。例えば、Springの@SessionScope
アノテーションスコープ名はハードコーディングされているsession
が、それでもカスタムが可能proxyMode
。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope(WebApplicationContext.SCOPE_SESSION)
public @interface SessionScope {
/**
* Alias for {@link Scope#proxyMode}.
* <p>Defaults to {@link ScopedProxyMode#TARGET_CLASS}.
*/
@AliasFor(annotation = Scope.class)
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}
その後、あなたは宣言する必要はありませんproxyMode
、以下を使用することができます@SessionScope
。
@Service
@SessionScope
public class SessionScopedService {
// ...
}
次の例に示すように、また、値proxyModeをカバーすることができます。
@Service
@SessionScope(proxyMode = ScopedProxyMode.INTERFACES)
public class SessionScopedUserService implements UserService {
// ...
}
1.10.3。自動的にクラス定義豆を検出し、登録
自動的にこれらのクラスを検出し、対応するBeanを登録するには、追加する必要がある@ComponentScan
に@Configuration
、クラス、basePackages
プロパティが共通の親パッケージがクラスに走査されています。(代わりに、カンマで区切られた、または各パケットは、親クラスを含み、セミコロンスペース区切りのリスト、で区切って指定することもできます。)
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
// ...
}
簡単にするため、前の例(すなわち、値のプロパティの注釈を使用することができます@ComponentScan("org.example")
)。
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="org.example"/>
</beans>
使用<context:component-scan>
暗黙的に有効<context:annotation-config>
な機能を。<context:annotation-config>
使用している場合、通常は含まれていない必要がある<context:component-scan>
要素を。
また、あなたはコンポーネント・スキャン要素を使用し、ときAutowiredAnnotationBeanPostProcessor
とCommonAnnotationBeanPostProcessor
暗黙のうちに含まれています。これらの2つのコンポーネントは自動的に検出し、それらを組み立て、そしてこのすべては、任意の豆のXML構成メタデータを提供する必要はありませんということ。この手段。
あなたは、登録を無効にすることができますAutowiredAnnotationBeanPostProcessor
し、CommonAnnotationBeanPostProcessor
設定することで、annotation-config
プロパティ値をfalse
。
1.10.4。カスタムスキャンフィルターを使用
デフォルトでは、コンポーネント@アノテーションの種類は、リポジトリ@、@サービス 、コントローラ、@Configuration、@ @Component伴うまたは自己定義された注釈自体検出された候補の唯一の成分です。ただし、アプリケーションによって、この動作を変更し、拡張するために、フィルタをカスタマイズすることができます。彼らは追加@ComponentScan
するincludeFilters
か、excludeFilters
属性(またはXMLの構成<context:component-scan>
要素<context:include-filter />
または<context:exclude-filter />
サブ要素)。各フィルタ要素のニーズtype
やexpression
特性を。次の表は、フィルタリングオプション(範囲タイプ属性)について説明
説明|例|フィルタタイプを
--- | | --- ---
注釈(デフォルト)| org.example.SomeAnnotation |ターゲットアセンブリにおけるタイプレベル存在または元のノートの存在。
アサイン| org.example.SomeClass |ターゲットコンポーネントは、クラス(またはインターフェース)に(または拡張実装)割り当てることができます。
AspectJの| org.example .. サービス+ | AspectJの型の式に一致するようにターゲットコンポーネント。
正規表現| org.example.Default。 |ターゲットコンポーネントの正規表現のクラス名を一致させます。
カスタム| org.example.MyTypeFilter | org.springframework.core.type.TypeFilterカスタムインターフェイスの実装。
@Configuration
@ComponentScan(basePackages = "org.example",
includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
excludeFilters = @Filter(Repository.class))
public class AppConfig {
...
}
<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>
また、注釈を設定することができuseDefaultFilters=false
、ラベルを提供することにより、またはuse-default-filters="false"
デフォルトのフィルタプロパティを無効にします。これは事実上の使用無効にし@Component
、@Repository
、@Service
、@Controller
、@RestController
、または@Configuration
自動検出素子注釈注釈またはクラス。
1.10.5。ビーン定義メタデータコンポーネント
@Component
public class FactoryMethodComponent {
@Bean
@Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
public void doWork() {
// Component method implementation omitted
}
}
@Bean
以下のように定義された値を持つノート植物の識別方法、および他の特性ビーン定義、@Qualifier
注釈付き。レベルのアノテーションを指定することができる他の方法があり@Scope
、@Lazy
およびカスタム注釈を定義します。
外部コンポーネントの初期化の役割に加えて、あなたも@Lazyに配置されたコメントでマークすることができます@Autowired
または@Inject
注入点に。この場合、遅延分解能エージェントにつながります。
上述したように、自動アセンブリフィールドとメソッドをサポートし、自動的に追加サポート@Bean方法をサポートします。これを行う方法を次の例が示します:
@Component
public class FactoryMethodComponent {
private static int i;
@Bean
@Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
// use of a custom qualifier and autowiring of method parameters
@Bean
protected TestBean protectedInstance(
@Qualifier("public") TestBean spouse,
@Value("#{privateInstance.age}") String country) {
TestBean tb = new TestBean("protectedInstance", 1);
tb.setSpouse(spouse);
tb.setCountry(country);
return tb;
}
@Bean
private TestBean privateInstance() {
return new TestBean("privateInstance", i++);
}
@Bean
@RequestScope
public TestBean requestScopedInstance() {
return new TestBean("requestScopedInstance", 3);
}
}
春のフレームワーク4.3の最初から、あなたも宣言することができるInjectionPoint
タイプ(またはそれ以上の特定のサブカテゴリーを:DependencyDescriptor
)ファクトリメソッドのパラメータを作成し、要求アクセストリガーポイント注射、現在のBeanに。これが唯一のBeanインスタンスの実際の作成に適用されることを、既存のインスタンスを注入するためには適用されません。そのため、この機能は、豆のプロトタイプ範囲の最も理にかなっています。他のスコープのために、ファクトリメソッドは、(例えば、依存性不活性単一の実施形態Beanの作成をトリガする)新たな注入点を作成するために、スコープBeanインスタンスのトリガーを参照して与えられます。この場合、注入点は、メタデータを用いてセマンティクスを備えていてもよいです。どのように使用するには、以下の例が示しますInjectionPoint
:
@Component
public class FactoryMethodComponent {
@Bean @Scope("prototype")
public TestBean prototypeInstance(InjectionPoint injectionPoint) {
return new TestBean("prototypeInstance for " + injectionPoint.getMember());
}
}
スプリングの組立従来の方法春@Bean @Configuration異なる取り扱いピアモード。違いはCGLIBは、メソッドやフィールドへのインターセプト呼び出しに@Componentクラスを高めない、ということです。CGLIBプロキシが協力したオブジェクトに豆のメタデータ参照を作成するには、この方法で@Configurationクラスメソッドまたはメソッド@Beanフィールドを呼び出す方法です。のではなく、コンテナによる単純なJavaの呼び出しのセマンティクスを使用するよりも、このような方法は、通常のライフサイクル管理と春の豆エージェントを提供するために、他のプログラムが参照する場合でも@Bean Beanメソッドを呼び出します。これとは対照的に、標準のJavaセマンティクス呼び出しが@Bean方法をフィールドや@Componentクラスは、一般的なエリア、特別な取り扱いやその他の制限CGLIBです。
あなたは、宣言されたメソッドを@Beanすることができますstatic
彼らはそれが含まれている構成例クラスの場合のコールを作成することができずに、。プロセッサビーン(例えば定義した後BeanFactoryPostProcessor
、またはBeanPostProcessor
そのような豆は、容器のライフサイクルの初期に初期化され、他の部分はトリガー設定時に避けなければならないので、特に興味深い時間型)、。
CGLIBサブクラスカバーのみ非静的メソッド:技術的な制限により、静的にメソッド呼び出しは、(このセクションで前述のように)クラスがあるため技術的な制限により、@Configurationない場合であっても、血管をブロックすることはない@Bean。結果として、別のインスタンスを生じる意味論的基準に別のJavaメソッド@Beanへの直接の呼び出しは、ファクトリメソッド自体から返されます。
Java言語の視認性@Bean方法はSpringコンテナのビーン定義の結果に直接影響を持っていません。あなたは非@コンフィギュレーションクラスを合わせて彼らのファクトリメソッドを宣言するのは自由です、静的メソッドは、任意の場所で使用することができます。しかし、従来の方法@Bean @コンフィギュレーションクラスは、言うことですつまり、書き換える必要がありますように宣言することはできませんprivate
かfinal
。
この方法はまた、所与のコンポーネントタイプまたは構成およびコンポーネントまたはクラス構成で実現インタフェースで宣言されたJava 8デフォルトメソッド@Beanベースクラスに見出すことができます。これは、春4.2で始まる、複雑な構成の配置の組み合わせのために大きな柔軟性を提供し、あるいは多重継承は、Java 8によってデフォルトの方法であってもよいです。
最後に、単一のクラスは、Beanの複数@Bean同じ方法を維持することができ、依存関係に応じてファクトリメソッドを複数配置し、実行時に利用可能です。これは、他の構成アルゴリズムにおける「最も貪欲」コンストラクタまたはファクトリメソッドの実施形態を選択することと同じである:変異体の最大数を有する選択された構成は、同様の容器@Autowiredコンストラクタ複数の間の依存関係を有する場合選択の行為。
1.10.6。名前のコンポーネントの自動検出
アセンブリは、自動的にスキャナ名豆で知られているスキャンプロセスの一部として検出された場合にBeanNameGenerator
ポリシー生成。デフォルトでは、任意のSpringステレオタイプアノテーション(成分@、リポジトリ@、@サービスと@Controller)、それによって対応するビーン定義の名前を提供し、名前の値を含みます。
この値は、注釈値が含まれていない、または任意の他のコンポーネントが含まれていませんが(例えば、カスタムフィルタ内のコンポーネントFOUNDによって)検出された場合は、デフォルトのBean名ジェネレータは、非修飾クラス名は大文字を使用していませんが返されます。例えば、コンポーネントクラスを検出し、名前はmyMovieLister movieFinderImplある場合:
@Service("myMovieLister")
public class SimpleMovieLister {
// ...
}
@Repository
public class MovieFinderImpl implements MovieFinder {
// ...
}
デフォルトの命名戦略ビーン、ビーンに依存したくない場合は、カスタムの命名ポリシーを提供することができます。まず第一に、BeanNameGeneratorインタフェースを実現し、デフォルトの引数なしのコンストラクタを含めるようにしてください。スキャナを設定するときに続いて、完全修飾クラス名は次の例のBean定義とコメントとして、提供しました:
@Configuration
@ComponentScan(basePackages = "org.example", nameGenerator = MyNameGenerator.class)
public class AppConfig {
// ...
}
<beans>
<context:component-scan base-package="org.example"
name-generator="org.example.MyNameGenerator" />
</beans>
他のコンポーネントを明示的に参照することができる時はいつでも一般的なルールとして、名前を指定するには、注釈を使用することを検討してください。一方、限り、コンテナが積載のために責任があるとして、自動生成された名前で十分です。
1.10.7。自動検出コンポーネントスコープを提供すること
@Scope("prototype")
@Repository
public class MovieFinderImpl implements MovieFinder {
// ...
}
@Scope
特に注意のみイントロスペクション(注釈付きコンポーネントの)Beanクラス又はファクトリメソッド(@Bean方法)。XMLビーン定義とは対照的に、そこに継承Beanの概念のない定義されていない、とクラスレベルの継承階層とメタデータの目的とは無関係です。
むしろ、達成することができ、アノテーションベースの方法に頼るよりも、距離分解能のカスタム戦略を提供するためScopeMetadataResolver
のインターフェイスを。デフォルト引数のないコンストラクタを必ず含めてください。その後、スキャナを設定する際、次の注意事項と豆の例で定義されているように、完全修飾クラス名を提供することが可能です。
@Configuration
@ComponentScan(basePackages = "org.example", scopeResolver = MyScopeResolver.class)
public class AppConfig {
// ...
}
<beans>
<context:component-scan base-package="org.example" scope-resolver="org.example.MyScopeResolver"/>
</beans>
いくつかの非単一スコープでは、スコープオブジェクトのプロキシを生成する必要があるかもしれません。この目的を達成するために、component-scan
要素が使用できるscoped-proxy
属性を。3つの値はno
:ある、interfaces
とtargetClass
。例えば、以下の構成が動的プロキシ標準JDKを生成します。
@Configuration
@ComponentScan(basePackages = "org.example", scopedProxy = ScopedProxyMode.INTERFACES)
public class AppConfig {
// ...
}
<beans>
<context:component-scan base-package="org.example" scoped-proxy="interfaces"/>
</beans>
1.10.8。提供修飾子メタデータ注釈付き
@Component
@Qualifier("Action")
public class ActionMovieCatalog implements MovieCatalog {
// ...
}
@Component
@Genre("Action")
public class ActionMovieCatalog implements MovieCatalog {
// ...
}
@Component
@Offline
public class CachingMovieCatalog implements MovieCatalog {
// ...
}
そして、ほとんど同じ代替に基づいて注釈を付け、覚えて、クラス定義自体、およびXMLの使用に結合注釈メタデータは、メタデータがあるので、それらの変異体修飾子のメタデータを複数提供するために、豆の同じタイプを可能にクラス別のプレスインスタンスではなく。
1.10.9。指標候補コンポーネントの生成
クラスパスのスキャンは非常に高速ですが、コンパイル時に候補者の静的リストを作成することにより、大規模なアプリケーションのパフォーマンスを向上させるために始めることができますが。このモードでは、スキャン対象の成分としてのモジュールの全ては、このメカニズムを使用しなければなりません。
既存@ComponentScan
または<context:component-scan>
コマンドは、いくつかの候補スキャン要求コンテキストパッケージにそのまま残っている必要があります。そのようなApplicationContextの指標を検出すると、自動的にスキャンパス型の代わりに使用します。
インデックスを生成するために、各モジュールの依存関係を含む追加のコンポーネントを追加する要求、これらの成分はターゲットコンポーネントスキャン指示です。Mavenを動作させるための方法を次の例が示します:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<version>5.2.1.RELEASE</version>
<optional>true</optional>
</dependency>
</dependencies>
次の例に示すように、Gradleの4.5およびそれ以前のバージョンのために、それは、compileOnly構成依存関係を宣言しなければなりません。
dependencies {
compileOnly "org.springframework:spring-context-indexer:5.2.1.RELEASE"
}
次の例に示すように、Gradleの4.6以降のため、構成がannotationProcessorは、依存関係を宣言しなければなりません。
dependencies {
annotationProcessor "org.springframework:spring-context-indexer:{spring-version}"
}
この手順は、瓶の中に含まれているファイルを生成META-INF/spring.components
ファイルを。
IDEにこのモードを使用する場合は、必要がありspring-context-indexer
、インデックスの更新候補コンポーネントが最新であることを保証するために、注釈プロセッサとして登録すること。
クラスパスに見つかりMETA-INF/spring.components
、インデックスが自動的に有効になります。あなたは、アプリケーション全体を構築することはできませんいくつかのライブラリ(またはユースケース)のインデックスが部分的に可能な場合は、しかし、あなたがすることができspring.index.ignore
設定としてtrue
クラスパスに退避すると、前後に(インデックスなしが存在しないかのように)、それはシステムに設定することができ、従来の手配します属性は、クラスのルートへのパスとして設定することができるspring.properties
ファイル。