春のドキュメントに従って
@Configurationクラスで使用するコンポーネントスキャンディレクティブを構成します。 Spring XMLの
<context:component-scan>
要素と並行してサポートを提供します。
私の春のWebアプリケーションには、春のコンテナに@Configuration
Beanを登録するために、@component
とマークされたファイルが複数あります-
Question1-@ComponentScan
を使用できますかいずれか@Configuration
クラスまたは全体@Configuration
クラス?
質問2-
春にも見た doc
@Configuration
@ComponentScan(basePackageClasses = { MyConfiguration.class })
public class MyConfiguration extends WebMvcConfigurerAdapter {
...
}
ここで構成クラス自体をスキャンする理由。
編集:@ComponentScan
の基本的な理解は、ステレオタイプBeanをスキャンして登録することです(ex- @componant
、@Controller
、@Services
など...)、なぜ@Configuration
Bean。
質問1について-
はい、あなたは@ComponentScan
を使用してBeanを登録できます構成Bean春のコンテナ。次のいずれかの方法でコンテナにBeanを登録できます-
rootcontext
またはdispatchersevletcontext
に@Configuration
Beanを登録するには。@Configuration
をBeanにインポートするには、すでにコンテナに登録されています。あなたがコンポーネントをスキャンしているMvcConfig
クラスがあるとしましょう-
@ComponentScan(basePackages = {"xxxx","yyyy","zzzz"})
@Configuration
public class MvcConfig {
....
}
MvcConfig
をコンテナーに登録するには、
どちらか
new AnnotationConfigWebApplicationContext().register(MvcConfig.class);
または
new AnnotationConfigWebApplicationContext().register(AnotherConfig.class);
@Configuration
@Import({MvcConfig.class})
public class AnotherConfig {
....
}
質問2について-
ここで、springはMyConfiguration.class
を登録するだけでなく、MyConfiguration
が定義されているパッケージに存在するすべてのコンポーネントクラスも登録しています。
質問1の解決策:
はい、_@Componentscan
_は多くの構成クラスで使用できます。それはあなた次第です。特定のパッケージのさまざまな注釈付きクラスをBeanとして登録するだけです。だからあなたが持っているなら すべて _@Componentscan
_を1つだけ使用してスキャンされた注釈付きクラスコンポーネント それは十分です、必要なすべてのBeanがアクティブ化され、DispatcherServletコンテナに登録されているため。
質問2の解決策:
_@Configuration
@ComponentScan(basePackageClasses = { MyConfiguration.class })
public class MyConfiguration extends WebMvcConfigurerAdapter {
...
}
_
あなたの質問: なぜここで構成クラス自体をスキャンするのですか?
この@ComponentScan(basePackageClasses = { MyConfiguration.class })
は、例としてMyConfiguration.classについて言及しています。問題は、これが何を意味するのかということです。
componentscanパッケージには、basepackage
属性またはbasepackageclasses
の2つの方法があります。これら2つは同じですが、basepackageclasses
を使用すると次の2つの利点があります。
タイプセーフであり、IDE今後のリファクタリングのサポートを追加します
つまり、将来、一部のベースバッケージの名前を(リファクタリングによって)変更できるようになります。ベースパッケージの名前を変更したので、使用した場合、構成クラスの@ComponentScanを変更する必要はありません。 basepackageclasses
属性。
次に、2番目の質問に戻ります。 MyConfiguration.classが_@Componentscan
_のbasepackageclasses
属性の値として指定されているのはなぜですか?
まず、これをお知らせください。basepackageclasses
属性は、いくつかのマーカークラスを表す文字列値を取ります。そのMarkerクラスは次のように伝えています。 おい!このクラスを含む、このクラスが含まれるパッケージにあるすべてのクラスを登録します。
したがって、ここでの回答では、MyConfiguration.classが存在するパッケージに存在するすべてのクラスがコンポーネントスキャンされます。
したがって、Myconfiguration.classは 構成 クラスだけでなく マーカー クラスからコンポーネントへの他のクラスもスキャンします。これは、@ Configurationアノテーションが付けられているMyConfiguration.classを含め、MyConfiguration.classが存在するパッケージに存在するすべてのアノテーション付きクラスが登録されることも意味します。basepackageclasses
属性には、_com.abc.org.Marker.class
_などの他のクラスも含めることができます
メリット:
そのため、パッケージの名前を変更しても、Springがパッケージを見つけるのに役立つマーカークラスがあるため、問題はありません。これらのマーカークラスは、パッケージを検索するためのマーカーとして機能するだけなので、内部にコンテンツがある場合とない場合があります。
ドキュメントから:
Q1:
@Configurationは@Componentでメタ注釈が付けられているため、@ Configurationクラスはコンポーネントスキャンの候補であり(通常はSpring XMLの要素を使用)、したがって、通常の@Componentと同様に@ Autowired/@ Injectを利用することもできます。
@Configurationクラスは、コンポーネントスキャンを使用してブートストラップされるだけでなく、@ ComponentScanを使用してコンポーネントスキャン自体を構成することもできますアノテーション:
@Configuration
@ComponentScan("com.acme.app.services")
public class AppConfig {
// various @Bean definitions ...
}
Q2:
basePackageClasses
public abstract Class<?>[] basePackageClasses
注釈付きコンポーネントをスキャンするパッケージを指定するためのbasePackages()のタイプセーフな代替手段。 指定された各クラスのパッケージがスキャンされます。
編集した質問の回答
ある時点で、アプリに必要なBeanがどこにあるかをSpringに伝える必要があります。たとえば、次のように使用できます。
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.scan("com.acme");
ctx.refresh();
MyService myService = ctx.getBean(MyService.class);
}
または古いxmlスタイルを使用:
<context:component-scan base-package="com.acme" />
@ConfigurationScanを@Configurationレベルで使用すると、その構成クラスのすべての依存関係が確実に利用できるようになります。 @CompenentScanをbasePackageClassesで使用すると、指定したクラスと同じパッケージで利用可能なすべてのコンポーネントが登録されます。
スキャンする必要があるパッケージを別の場所または方法でSpringにすでに通知している場合は、それを使用する必要はありません。 Q2のコードは、Springが実行できることのほんの一例です。