特定の@ComponentScan
の@Configuration
から除外したいコンポーネントがあります:
@Component("foo") class Foo {
...
}
そうでなければ、私のプロジェクトの他のクラスと衝突するようです。衝突を完全には理解していませんが、@Component
注釈をコメントアウトすると、期待どおりに動作します。しかし、このライブラリに依存する他のプロジェクトは、このクラスがSpringによって管理されることを想定しているため、自分のプロジェクトでのみこのクラスをスキップします。
@ComponentScan.Filter
を使用してみました:
@Configuration
@EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
しかし、動作していないようです。 FilterType.ASSIGNABLE_TYPE
を使用しようとすると、ランダムに見えるクラスをロードできないという奇妙なエラーが表示されます。
原因:Java.io.FileNotFoundException:クラスパスリソース[junit/framework/TestCase.class]は存在しないため開くことができません
また、次のようにtype=FilterType.CUSTOM
を使用してみました:
class ExcludeFooFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader,
MetadataReaderFactory metadataReaderFactory) throws IOException {
return metadataReader.getClass() == Foo.class;
}
}
@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
しかし、それは私が望むようにスキャンからコンポーネントを除外するようには見えません。
除外するにはどうすればよいですか?
excludeFilters
の代わりにexcludes
を使用する必要があることを除いて、構成は問題ないように見えます。
@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
スキャンフィルターで明示的な型を使用するのはmeいです。よりエレガントなアプローチは、独自のマーカー注釈を作成することです。
public @interface IgnoreDuringScan {
}
除外するコンポーネントにそれをマークします。
@Component("foo")
@IgnoreDuringScan
class Foo {
...
}
コンポーネントスキャンからこの注釈を除外します。
@ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class))
public class MySpringConfiguration {}
別のアプローチは、新しい条件付き注釈を使用することです。 plain Spring 4なので、@ Conditionalアノテーションを使用できます。
@Component("foo")
@Conditional(FooCondition.class)
class Foo {
...
}
fooコンポーネントを登録するための条件ロジックを定義します。
public class FooCondition implements Condition{
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// return [your conditional logic]
}
}
Beanファクトリにアクセスできるため、条件ロジックはコンテキストに基づいて作成できます。たとえば、「Bar」コンポーネントがBeanとして登録されていない場合:
return !context.getBeanFactory().containsBean(Bar.class.getSimpleName());
Spring Boot(すべての新しいSpringプロジェクトに使用する必要があります)では、これらの条件付き注釈を使用できます:
@ConditionalOnBean
@ConditionalOnClass
@ConditionalOnExpression
@ConditionalOnJava
@ConditionalOnMissingBean
@ConditionalOnMissingClass
@ConditionalOnNotWebApplication
@ConditionalOnProperty
@ConditionalOnResource
@ConditionalOnWebApplication
この方法で条件クラスの作成を回避できます。詳細については、Spring Bootのドキュメントを参照してください。
2つ以上のexcludeFilters基準を定義する必要がある場合は、配列を使用する必要があります。
このコードセクションのインスタンスでは、org.xxx.yyyパッケージと別の特定のクラスMyClassToExcludeのすべてのクラスを除外します
@ComponentScan(
excludeFilters = {
@ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.xxx.yyy.*"),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyClassToExclude.class) })
@ Configuration、@ EnableAutoConfigurationおよび@ ComponentScan特定の構成クラスを除外しようとしても、うまくいかなかったのです!
最終的に、私は @ SpringBootApplication を使用して問題を解決しました。注釈。
もう1つのヒントは、パッケージスキャンを調整せずに(basePackagesフィルターなしで)最初に試すことです。
@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}
テストコンポーネントまたはテスト構成を除外する場合、Spring Boot 1.4は新しいテストアノテーション @TestComponent
および@TestConfiguration
を導入しました。
アプリコンテキストから監査@Aspect @Componentを除外する必要がありましたが、いくつかのテストクラスについてのみです。アスペクトクラスで@Profile( "audit")を使用することになりました。特定のテストクラスで通常の操作のプロファイルを含めますが、それを除外します(@ActiveProfilesに入れないでください)。