103

@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.CUSTOM, value=ExcludeFooFilter.class)})
public class MySpringConfiguration {}

しかし、それは私が望むようにコンポーネントをスキャンから除外していないようです。

どうすれば除外できますか?

4

7 に答える 7

126

The configuration seem alright, except that you should use excludeFilters instead of excludes:

@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
  @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
于 2013-09-24T22:39:12.503 に答える
33

もう 1 つの方法は、新しい条件付き注釈を使用することです。プレーンな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

この方法で Condition クラスの作成を回避できます。詳細については、Spring Boot のドキュメントを参照してください。

于 2014-12-06T16:11:04.913 に答える
16

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) })
于 2017-06-22T14:30:25.730 に答える