@ কম্পোনেন্টসস্ক্যান থেকে @ কম্পোনেন্টটি বাদ দিন


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: শ্রেণি পথের সংস্থান [জুনিট / ফ্রেমওয়ার্ক / টেস্টক্যাস.ক্লাস] খোলা যায় না কারণ এটি বিদ্যমান নেই

আমি 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 {}

দুঃখিত, এটি একটি কাটা এবং পেস্ট ত্রুটি ছিল। আমি এক্সক্লুড ফিল্টার ব্যবহার করছি। আমি অন্য বর্ণন, ত্রুটি এই দেয় আমাকে সত্যিই উদ্ভট হচ্ছে ... নেব
ykaganovich

52

স্ক্যান ফিল্টারগুলিতে সুস্পষ্ট ধরনের ব্যবহার করা আমার পক্ষে কুৎসিত। আমি বিশ্বাস করি যে আরও মার্জিত পদ্ধতি হ'ল নিজস্ব চিহ্নিতকারী তৈরি করা:

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

উপাদানটি চিহ্নিত করুন যা এটির সাথে বাদ দেওয়া উচিত:

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

এবং এই উপাদানটি আপনার উপাদান স্ক্যান থেকে বাদ দিন:

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

13
এটি সর্বজনীন বর্জনের জন্য একটি চতুর ধারণা যদিও আপনি কোনও প্রকল্পের অ্যাপ্লিকেশন প্রসঙ্গে কেবলমাত্র একটি উপসর্গ থেকে কোনও উপাদান বাদ দিতে চাইলে সহায়তা করবে না। সত্যিই, তা বিশ্বজুড়ে অগ্রাহ্য করা হবে এক মাত্র দূর করতে পারবে @Component, কিন্তু আমি যে কি প্রশ্ন জিজ্ঞাসা করা হয় মনে করি না
কারবি

4
আপনার যদি অন্য কোনও উপাদান স্ক্যানের টীকাগুলির একই ফিল্টার না থাকে তবে এটি কাজ করবে না
বাশার আলী লাবাদি

@ বাশার আলী লাবাদী, এই নির্মাণের মতো বিন্দুটি কি নয়? আপনি যদি এটি সমস্ত উপাদান স্ক্যান থেকে বাদ দিতে চান তবে এটি সম্ভবত স্প্রিং উপাদান নয়।
luboskrnac

30

আরেকটি পদ্ধতির মধ্যে রয়েছে নতুন শর্তযুক্ত টীকাগুলি। যেহেতু প্লেইন বসন্ত 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]
    }     
}

শর্তযুক্ত যুক্তি প্রসঙ্গের ভিত্তিতে তৈরি করা যেতে পারে, কারণ আপনার শিম কারখানায় অ্যাক্সেস রয়েছে। উদাহরণস্বরূপ যখন "বার" উপাদানটি শিম হিসাবে নিবন্ধিত না হয়:

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

স্প্রিং বুট সহ (প্রতিটি নতুন স্প্রিং প্রকল্পের জন্য ব্যবহার করা উচিত), আপনি এই শর্তযুক্ত মন্তব্যগুলি ব্যবহার করতে পারেন:

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

আপনি এইভাবে কন্ডিশন শ্রেণির সৃষ্টি এড়াতে পারবেন। আরও বিস্তারিত জানার জন্য স্প্রিং বুট ডক্স দেখুন।


4
শর্তাবলীর জন্য +1, ফিল্টার ব্যবহারের চেয়ে এটি আমার কাছে আরও পরিষ্কার উপায়। শিমের শর্তসাপেক্ষ লোডিংয়ের মতো ধারাবাহিকভাবে কাজ করার জন্য আমি ফিল্টারগুলি এখনও পাই নি
আশ্চর্যজনকভাবে 77

13

ফিলিটারের মানদণ্ডে দু'একটি বেশি বাছাই করতে গেলে আপনাকে অ্যারে ব্যবহার করতে হবে।

কোডের এই বিভাগে উদাহরণস্বরূপ আমি org.xxx.yyy প্যাকেজ এবং অন্য নির্দিষ্ট শ্রেণীর সমস্ত ক্লাস, মাইক্লাসটোওএক্সক্লাডকে বাদ দিতে চাই

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

আমি ফিল্ডের ধরণ হিসাবে এএসপিসিটিজে পরামর্শ দেব, কারণ এই রেজেক্সটি "org.xxx.yyyy.z" এর
সাথেও মিলবে

9

@ কনফিগারেশন , @EnableAutoConfigration এবং @Comp घटक Scan নির্দিষ্ট কনফিগারেশন ক্লাস বাদ দেওয়ার চেষ্টা করার সময় আমার একটি সমস্যা হয়েছিল , জিনিসটি এটি কার্যকর হয়নি!

অবশেষে আমি @ স্প্রিংবুট অ্যাপ্লিকেশন ব্যবহার করে সমস্যার সমাধান করেছি , যা স্প্রিং ডকুমেন্টেশন অনুসারে একটি টিকাতে উপরের তিনটির মতো একই কার্যকারিতা করে।

অন্য টিপটি হ'ল আপনার প্যাকেজ স্ক্যানটিকে (বাজপেজগুলি ফিল্টার ছাড়াই) পরিশোধিত না করে প্রথমে চেষ্টা করা।

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

আমি এটি চেষ্টা করেছি কিন্তু "নিম্নলিখিত ক্লাসগুলি স্বতঃ-কনফিগারেশন ক্লাস নয় বলে বাদ দেওয়া যায়নি" হিসাবে ত্রুটি দেখিয়েছি। @ কম্পোনেন্টস্ক্যান সহ ফিল্টারগুলি ভাল কাজ করছে।
AzarEJ


0

আমার অ্যাপ্লিকেশন প্রসঙ্গটি থেকে একটি অডিটিং @ স্পেক্ট @ কমপোমেন্টকে বাদ দিতে হবে তবে কেবল কয়েকটি পরীক্ষা ক্লাসের জন্য। আমি @Profile ("নিরীক্ষণ") দিকটি ক্লাসে ব্যবহার করে শেষ করেছি; সাধারণ ক্রিয়াকলাপের জন্য প্রোফাইল সহ তবে নির্দিষ্ট পরীক্ষার ক্লাসে এটি বাদ দিয়ে (এটি @ অ্যাক্টিভ প্রফাইলে রাখবেন না)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.