@ComponentScan से @Component को बाहर करें


90

मेरे पास एक घटक है जिसे मैं @ComponentScanएक विशेष में से बाहर करना चाहता हूं @Configuration:

@Component("foo") class Foo {
...
}

अन्यथा, यह मेरी परियोजना में किसी अन्य वर्ग के साथ टकराव लगता है। मैं पूरी तरह से टकराव को नहीं समझता, लेकिन अगर मैं @Componentएनोटेशन पर टिप्पणी करता हूं , तो चीजें काम करती हैं जैसे मैं उन्हें चाहता हूं। लेकिन अन्य परियोजनाएं जो इस पुस्तकालय पर भरोसा करती हैं, उम्मीद करती हैं कि यह वर्ग स्प्रिंग द्वारा प्रबंधित किया जाएगा, इसलिए मैं इसे केवल अपनी परियोजना में छोड़ना चाहता हूं।

मैंने प्रयोग करने की कोशिश की @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 / फ्रेमवर्क / 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 {}

लेकिन मुझे लगता है कि जैसे स्कैन से घटक को बाहर नहीं लगता है।

मैं इसे कैसे बाहर करूं?

जवाबों:


107

कॉन्फ़िगरेशन ठीक प्रतीत होता है, सिवाय इसके कि आपको excludeFiltersइसके बजाय उपयोग करना चाहिए excludes:

@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
  @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}

क्षमा करें, यह एक कट और पेस्ट त्रुटि थी। मैं बहिष्कृत का उपयोग कर रहा हूँ। मैं एक और नज़र
डालूँगा

52

स्कैन फिल्टर में स्पष्ट प्रकार का उपयोग करना मेरे लिए बदसूरत है। मेरा मानना ​​है कि खुद के मार्कर एनोटेशन बनाने के लिए अधिक सुरुचिपूर्ण दृष्टिकोण है:

@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreDuringScan {
}

मार्क घटक जिसे इसके साथ बाहर रखा जाना चाहिए:

@Component("foo") 
@IgnoreDuringScan
class Foo {
    ...
}

और अपने घटक स्कैन से इस एनोटेशन को बाहर करें:

@ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class))
public class MySpringConfiguration {}

13
यह सार्वभौमिक बहिष्करण के लिए एक चतुर विचार है, हालांकि यदि आप एक घटक को केवल एक प्रोजेक्ट में एप्लिकेशन संदर्भों के सबसेट से बाहर करना चाहते हैं तो मदद नहीं करेगा। वास्तव में, इसे सार्वभौमिक रूप से बाहर करने के लिए, कोई भी इसे हटा सकता है @Component, लेकिन मुझे नहीं लगता कि यह सवाल क्या है
किर्बी

2
यह काम नहीं करेगा यदि आपके पास एक और घटक स्कैन एनोटेशन है जिसमें एक ही फिल्टर नहीं है
बशर अली लबाड़ी

@ बशर अली लबाड़ी, इस तरह के निर्माण की बात नहीं कर रहे हैं? यदि आप इसे सभी घटक स्कैन से बाहर करना चाहते हैं, तो संभवतः यह स्प्रिंग घटक बिल्कुल नहीं होना चाहिए।
luboskrnac

30

एक और दृष्टिकोण नए सशर्त एनोटेशन का उपयोग करना है। सादे वसंत 4 के बाद से आप @ टिप्पणी का उपयोग कर सकते हैं:

@Component("foo")
@Conditional(FooCondition.class)
class Foo {
    ...
}

और फू घटक को पंजीकृत करने के लिए सशर्त तर्क को परिभाषित करें:

public class FooCondition implements Condition{
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // return [your conditional logic]
    }     
}

सशर्त तर्क संदर्भ पर आधारित हो सकते हैं, क्योंकि आपके पास बीन फैक्ट्री तक पहुंच है। उदाहरण के लिए जब "बार" घटक बीन के रूप में पंजीकृत नहीं है:

    return !context.getBeanFactory().containsBean(Bar.class.getSimpleName());

स्प्रिंग बूट के साथ (हर नए स्प्रिंग प्रोजेक्ट के लिए इस्तेमाल किया जाना चाहिए), आप इन सशर्त एनोटेशन का उपयोग कर सकते हैं:

  • @ConditionalOnBean
  • @ConditionalOnClass
  • @ConditionalOnExpression
  • @ConditionalOnJava
  • @ConditionalOnMissingBean
  • @ConditionalOnMissingClass
  • @ConditionalOnNotWebApplication
  • @ConditionalOnProperty
  • @ConditionalOnResource
  • @ConditionalOnWebApplication

आप इस तरह हालत वर्ग निर्माण से बच सकते हैं। अधिक विस्तार के लिए स्प्रिंग बूट डॉक्स देखें।


1
कंडीशंस के लिए +1, फिल्टर का उपयोग करने की तुलना में मेरे लिए यह एक अधिक स्वच्छ तरीका है। मैं कभी भी सेम के सशर्त लोडिंग के रूप में लगातार काम करने के लिए फिल्टर नहीं मिला है
Wondergoat77

13

मामले में आपको दो या दो से अधिक बहिष्कृत परिभाषित करने की आवश्यकता है मानदंडों है, तो आपको सरणी का उपयोग करना होगा।

कोड के इस खंड में उदाहरणों के लिए मैं org.xxx.yyy पैकेज और अन्य विशिष्ट वर्ग, MyClassToExclude में सभी वर्गों को बाहर करना चाहता हूं।

 @ComponentScan(            
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.xxx.yyy.*"),
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyClassToExclude.class) })

मैं फ़िल्टर प्रकार के रूप में ASPECTJ का सुझाव दूंगा, क्योंकि यह रेगेक्स "org.xxx.yyyy.z" से भी मेल खाएगा
wutzebaer

9

मेरे पास @Configuration का उपयोग करते समय एक समस्या थी , @EnableAutoConfiguration और @ComponentScan विशिष्ट कॉन्फ़िगरेशन वर्गों को बाहर करने की कोशिश करते हुए , बात यह है कि यह काम नहीं किया!

अंततः मैंने @SpringBootApplication का उपयोग करके समस्या को हल किया , जो कि स्प्रिंग डॉक्यूमेंटेशन के अनुसार एक एनोटेशन में उपरोक्त तीनों के समान कार्यक्षमता करता है।

एक और टिप आपके पैकेज स्कैन (बिना बेसपेक फिल्टर के) को परिष्कृत किए बिना पहले प्रयास करना है।

@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}

मैंने यह कोशिश की है, लेकिन "निम्न वर्ग को ऑटो-कॉन्फ़िगरेशन कक्षा नहीं होने के कारण निम्न वर्गों को बाहर नहीं किया जा सकता" के रूप में त्रुटि दिखा रहा है। @ComponentScan के साथ बहिष्करण ठीक काम कर रहा है।
अजारई

1

परीक्षण घटक या परीक्षण कॉन्फ़िगरेशन को बाहर करने के मामले में, स्प्रिंग बूट 1.4 ने नए परीक्षण एनोटेशन @TestComponentऔर@TestConfiguration पेश किए ।


0

मुझे ऐप के संदर्भ से @ ऑस्पेक्ट @ कॉमपोनेंट को केवल कुछ परीक्षण कक्षाओं के लिए एक ऑडिटिंग को बाहर करने की आवश्यकता थी। मैंने पहलू वर्ग पर @Profile ("ऑडिट") का उपयोग करके समाप्त किया; सामान्य परिचालनों के लिए प्रोफ़ाइल शामिल है, लेकिन विशिष्ट परीक्षण कक्षाओं पर इसे छोड़कर (@ActiveProfiles में इसे न डालें)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.