欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于@ComponentScan注解的使用詳解

 更新時(shí)間:2021年08月16日 11:18:29   作者:Code0cean  
這篇文章主要介紹了@ComponentScan注解的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

@ComponentScan注解的使用

一、注解定義

@ComponentScan注解的定義如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
   /**
    * 掃描路徑
    * @ComponentScan(value = "spring.annotation.componentscan")
    */
   @AliasFor("basePackages")
   String[] value() default {};
   /**
    * 掃描路徑
    */
   @AliasFor("value")
   String[] basePackages() default {};
   /**
    * 指定掃描類
    * @ComponentScan(basePackageClasses = {BookDao.class, BookService.class})
    */
   Class<?>[] basePackageClasses() default {};
   /**
    * 命名注冊(cè)的Bean,可以自定義實(shí)現(xiàn)命名Bean,
    * 1、@ComponentScan(value = "spring.annotation.componentscan",nameGenerator = MyBeanNameGenerator.class)
    * MyBeanNameGenerator.class 需要實(shí)現(xiàn) BeanNameGenerator 接口,所有實(shí)現(xiàn)BeanNameGenerator 接口的實(shí)現(xiàn)類都會(huì)被調(diào)用
    * 2、使用 AnnotationConfigApplicationContext 的 setBeanNameGenerator方法注入一個(gè)BeanNameGenerator
    * BeanNameGenerator beanNameGenerator = (definition,registry)-> String.valueOf(new Random().nextInt(1000));
    * AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
    * annotationConfigApplicationContext.setBeanNameGenerator(beanNameGenerator);
    * annotationConfigApplicationContext.register(MainConfig2.class);
    * annotationConfigApplicationContext.refresh();
    * 第一種方式只會(huì)重命名@ComponentScan掃描到的注解類
    * 第二種只有是初始化的注解類就會(huì)被重命名
    * 列如第一種方式不會(huì)重命名 @Configuration 注解的bean名稱,而第二種就會(huì)重命名 @Configuration 注解的Bean名稱
    */
   Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
   /**
    * 用于解析@Scope注解,可通過 AnnotationConfigApplicationContext 的 setScopeMetadataResolver 方法重新設(shè)定處理類
    * ScopeMetadataResolver scopeMetadataResolver = definition -> new ScopeMetadata();  這里只是new了一個(gè)對(duì)象作為演示,沒有做實(shí)際的邏輯操作
    * AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
    * annotationConfigApplicationContext.setScopeMetadataResolver(scopeMetadataResolver);
    * annotationConfigApplicationContext.register(MainConfig2.class);
    * annotationConfigApplicationContext.refresh();
    * 也可以通過@ComponentScan 的 scopeResolver 屬性設(shè)置
    *@ComponentScan(value = "spring.annotation.componentscan",scopeResolver = MyAnnotationScopeMetadataResolver.class)
    */
   Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
   /**
    * 用來設(shè)置類的代理模式
    */
   ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
   /**
    * 掃描路徑 如 resourcePattern = "**/*.class"
    * 使用  includeFilters 和 excludeFilters 會(huì)更靈活
    */
   String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
   /**
    * 指示是否應(yīng)啟用對(duì)帶有{@code @Component},{@ code @Repository},
    * {@ code @Service}或{@code @Controller}注釋的類的自動(dòng)檢測(cè)。
    */
   boolean useDefaultFilters() default true;
   /**
    * 對(duì)被掃描的包或類進(jìn)行過濾,若符合條件,不論組件上是否有注解,Bean對(duì)象都將被創(chuàng)建
    * @ComponentScan(value = "spring.annotation.componentscan",includeFilters = {
    *     @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class}),
    *     @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {SchoolDao.class}),
    *     @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class}),
    *     @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "spring.annotation..*"),
    *     @ComponentScan.Filter(type = FilterType.REGEX, pattern = "^[A-Za-z.]+Dao$")
    * },useDefaultFilters = false)
    * useDefaultFilters 必須設(shè)為 false
    */
   Filter[] includeFilters() default {};
   /**
    * 指定哪些類型不適合進(jìn)行組件掃描。
    * 用法同 includeFilters 一樣
    */
   Filter[] excludeFilters() default {};
   /**
    * 指定是否應(yīng)注冊(cè)掃描的Bean以進(jìn)行延遲初始化。
    * @ComponentScan(value = "spring.annotation.componentscan",lazyInit = true)
    */
   boolean lazyInit() default false;
   /**
    * 用于 includeFilters 或 excludeFilters 的類型篩選器
    */
   @Retention(RetentionPolicy.RUNTIME)
   @Target({})
   @interface Filter {
      /**
       * 要使用的過濾器類型,默認(rèn)為 ANNOTATION 注解類型
       * @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})
       */
      FilterType type() default FilterType.ANNOTATION;
      /**
       * 過濾器的參數(shù),參數(shù)必須為class數(shù)組,單個(gè)參數(shù)可以不加大括號(hào)
       * 只能用于 ANNOTATION 、ASSIGNABLE_TYPE 、CUSTOM 這三個(gè)類型
       * @ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class, Service.class})
       * @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {SchoolDao.class})
       * @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
       */
      @AliasFor("classes")
      Class<?>[] value() default {};
      /**
       * 作用同上面的 value 相同
       * ANNOTATION 參數(shù)為注解類,如  Controller.class, Service.class, Repository.class
       * ASSIGNABLE_TYPE 參數(shù)為類,如 SchoolDao.class
       * CUSTOM  參數(shù)為實(shí)現(xiàn) TypeFilter 接口的類 ,如 MyTypeFilter.class
       * MyTypeFilter 同時(shí)還能實(shí)現(xiàn) EnvironmentAware,BeanFactoryAware,BeanClassLoaderAware,ResourceLoaderAware 
       * 這四個(gè)接口
       * EnvironmentAware
       * 此方法用來接收 Environment 數(shù)據(jù) ,主要為程序的運(yùn)行環(huán)境,Environment 接口繼承自 PropertyResolver 接口,
       * 詳細(xì)內(nèi)容在下方
       * @Override
       * public void setEnvironment(Environment environment) {
       *    String property = environment.getProperty("os.name");
       * }
       * 
       * BeanFactoryAware
       * BeanFactory Bean容器的根接口,用于操作容器,如獲取bean的別名、類型、實(shí)例、是否單例的數(shù)據(jù)
       * @Override
       * public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
       *     Object bean = beanFactory.getBean("BeanName")
       * }
       * 
       * BeanClassLoaderAware
       * ClassLoader 是類加載器,在此方法里只能獲取資源和設(shè)置加載器狀態(tài)
       * @Override
       * public void setBeanClassLoader(ClassLoader classLoader) {
       *     ClassLoader parent = classLoader.getParent();
       * }
       * 
       * ResourceLoaderAware
       * ResourceLoader 用于獲取類加載器和根據(jù)路徑獲取資源
       * public void setResourceLoader(ResourceLoader resourceLoader) {
       *     ClassLoader classLoader = resourceLoader.getClassLoader();
       * }
       */
      @AliasFor("value")
      Class<?>[] classes() default {};
      /**
       * 這個(gè)參數(shù)是 classes 或 value 的替代參數(shù),主要用于 ASPECTJ 類型和  REGEX 類型
       * ASPECTJ  為 ASPECTJ 表達(dá)式
       * @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "spring.annotation..*")
       * REGEX  參數(shù)為 正則表達(dá)式
       * @ComponentScan.Filter(type = FilterType.REGEX, pattern = "^[A-Za-z.]+Dao$")
       */
      String[] pattern() default {};
   }
}

二、使用

1.環(huán)境準(zhǔn)備

創(chuàng)建Maven項(xiàng)目,添加依賴:

  <dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-context</artifactId>
		    <version>4.3.26.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/junit/junit -->
		<dependency>
		  <groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>	
  </dependencies>

創(chuàng)建bean,controller,dao,service層,并在類上加上對(duì)應(yīng)的注解,項(xiàng)目結(jié)構(gòu)如下:

在這里插入圖片描述

編寫測(cè)試類,如下:

public class IoCTest {
	@Test
	public void test01() {
		//獲取Spring的IOC容器
		ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);
		//從容器中獲取bean
	    String[] names= applicationContext.getBeanDefinitionNames();	
	       for(String i:names) {
	    	   System.out.println(i);
	       }
	}
}

2.excludeFilters的使用

使用excludeFilters不掃描com.learn包中的Controller、Service注解,如下:

@Configuration
@ComponentScan(basePackages = "com.learn",excludeFilters = {
  @Filter(type = FilterType.ANNOTATION,classes = {Controller.class,Service.class})
})
public class SpringConfig {
}

上面使用的excludeFilters用于設(shè)置排除的過濾條件,實(shí)現(xiàn)Filter接口的type屬性用于設(shè)置過濾類型,默認(rèn)值為FilterType.ANNOTATION,提供了這幾個(gè)過濾類型:

  • FilterType.ANNOTATION:按照注解過濾
  • FilterType.ASSIGNABLE_TYPE:按照給定的類型過濾
  • FilterType.ASPECTJ:按照ASPECTJ表達(dá)式過濾
  • FilterType.REGEX:按照正則表達(dá)式過濾
  • FilterType.CUSTOM:按照自定義規(guī)則過濾

classes和value屬性為過濾器的參數(shù),必須為class數(shù)組,類只能為以下三種類型:

  • ANNOTATION 參數(shù)為注解類,如 Controller.class, Service.class,Repository.class
  • ASSIGNABLE_TYPE 參數(shù)為類,如 SchoolDao.class
  • CUSTOM 參數(shù)為實(shí)現(xiàn) TypeFilter 接口的類 ,如 MyTypeFilter.class

3.includeFilters的使用

includeFilters屬性用于定義掃描過濾條件,滿足該條件才進(jìn)行掃描。用法與excludeFilters一樣。

但是因?yàn)閡seDefaultFilters屬性默認(rèn)為true,即使用默認(rèn)的過濾器,啟用對(duì)帶有@Component,@Repository,@Service,@Controller注釋的類的自動(dòng)檢測(cè)。會(huì)將帶有這些注解的類注冊(cè)為bean裝配到IoC容器中。所以使用includeFilters時(shí),需要把useDefaultFilters設(shè)置為false,如下:

@Configuration
@ComponentScan(basePackages = "com.learn",includeFilters = {
  @Filter(type = FilterType.ANNOTATION,classes = {Controller.class,Service.class})
},useDefaultFilters = false)
public class SpringConfig {
}

結(jié)果如下,只掃描了帶有Controller,Service注解的自定義的類:

在這里插入圖片描述

4.自定義過濾規(guī)則

@ComponentScan注解掃描或解析的bean只能是Spring內(nèi)部所定義的,比如@Component、@Service、@Controller或@Repository。如果要掃描一些自定義的注解,就可以自定義過濾規(guī)則來完成這個(gè)操作。

自定義一個(gè)類MyTypeFilter實(shí)現(xiàn)TypeFilter接口,這樣這個(gè)TypeFilter就掃描所有類并只通過類名包含了controller的類,如下:

public class MyTypeFilter implements TypeFilter {
    /**
     * 兩個(gè)參數(shù)的含義:
     * metadataReader:包含讀取到的當(dāng)前正在掃描的類的信息
     * metadataReaderFactory:可以獲取到當(dāng)前正在掃描的類的其他類信息(如父類和接口)
     * match方法返回false即不通過過濾規(guī)則,true通過過濾規(guī)則
     */
	@Override
	public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {
		// TODO Auto-generated method stub
	     //獲取當(dāng)前類注解的信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //獲取當(dāng)前正在掃描的類的類信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        //獲取當(dāng)前類資源(類的路徑)
        Resource resource = metadataReader.getResource();
        String className = classMetadata.getClassName();
        if(className.contains("controller")){
            return true;
        }
        return false;
	}
}

在@ComponentScan注解中進(jìn)行配置,如下:

@Configuration
@ComponentScan(basePackages = "com.learn",includeFilters = {
		@Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Person.class}),
		@Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class}),
},useDefaultFilters = false)
public class SpringConfig {
}

經(jīng)過上面的配置,第一個(gè)@Filter通過FilterType.ASSIGNABLE_TYPE規(guī)定了只掃描Person類型的類,第二個(gè)@Filter通過FilterType.CUSTOM自定義過濾規(guī)則規(guī)定了只掃描類名包含controller的類。結(jié)果:

在這里插入圖片描述

關(guān)于@ComponentScan注解的一些細(xì)節(jié)

@ComponentScan注解可以掃描 任意 類 或者 注解 中內(nèi)部類bean;

要想被掃描的前提是內(nèi)部類標(biāo)注了@Component及其相關(guān)衍生注解、內(nèi)部類必須是static修飾,否則掃描不到;如果是注解的內(nèi)部類則只能是public static修飾

//@Configuration
public class ProfileConfig {
    @Component("class1")
    private static class Class1 {
        @Bean
        public Class3 class3() {
            return new Class3();
        }
    }
    @Component("class2")
    static class Class2 {
    }
    //@Component("class3")
    protected static class Class3 {
    }
//    @Component("class4") //出錯(cuò)
//    protected class Class4 {
//
//    }
}
--------------------------------------------------------
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
//@Bean
public @interface MyBean {
    public static final int age1=3; //常量可以
    int age=2;
    public abstract String value() default "qwer"; //屬性可以
    //內(nèi)部類可以
    @Component
    @DependsOn("myBean.EventZ") //依賴事件bean的創(chuàng)建,保證該bean在事件bean之后創(chuàng)建
        //細(xì)節(jié):因?yàn)槭莾?nèi)部類,所以默認(rèn)bean的id是類名首字母小寫,不是eventZ而是myBean.EventZ
    class EventSource {
        public EventSource(){
            System.out.println("事件源創(chuàng)建了...");
        }
    }
    @Component//("eventZ")
    public static class EventZ {
        public EventZ(){
            System.out.println("事件創(chuàng)建了...");
        }
    }
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 重新啟動(dòng)IDEA時(shí)maven項(xiàng)目SSM框架文件變色所有@注解失效

    重新啟動(dòng)IDEA時(shí)maven項(xiàng)目SSM框架文件變色所有@注解失效

    這篇文章主要介紹了重新啟動(dòng)IDEA時(shí)maven項(xiàng)目SSM框架文件變色所有@注解失效,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Java I/O技術(shù)之文件操作詳解

    Java I/O技術(shù)之文件操作詳解

    這篇文章主要介紹了Java I/O技術(shù)之文件操作詳解,需要的朋友可以參考下
    2014-07-07
  • java中double類型運(yùn)算結(jié)果異常的解決方法

    java中double類型運(yùn)算結(jié)果異常的解決方法

    下面小編就為大家?guī)硪黄猨ava中double類型運(yùn)算結(jié)果異常的解決方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • 超級(jí)好用的輕量級(jí)JSON處理命令jq(最新推薦)

    超級(jí)好用的輕量級(jí)JSON處理命令jq(最新推薦)

    jq是一個(gè)輕量級(jí)的命令行工具,讓你可以非常方便地處理JSON數(shù)據(jù),如切分、過濾、映射、轉(zhuǎn)化等,就像sed、awk、grep文本處理三劍客一樣,這篇文章主要介紹了超級(jí)好用的輕量級(jí)JSON處理命令jq,需要的朋友可以參考下
    2023-01-01
  • Java單例模式的幾種常見寫法

    Java單例模式的幾種常見寫法

    這篇文章主要介紹了Java單例模式的幾種寫法,單例模式是面試中的??土耍R妼懛ㄓ?4?種:餓漢模式、懶漢模式、靜態(tài)內(nèi)部類和枚舉,接下來我們一起進(jìn)入文章看看吧
    2022-05-05
  • java設(shè)計(jì)模式之單例模式解析

    java設(shè)計(jì)模式之單例模式解析

    這篇文章主要為大家詳細(xì)介紹了java設(shè)計(jì)模式之單例模式的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • java nio中的ByteBuffer擴(kuò)展問題

    java nio中的ByteBuffer擴(kuò)展問題

    這篇文章主要介紹了java nio中的ByteBuffer擴(kuò)展問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 為什么阿里巴巴要求日期格式化時(shí)必須有使用y表示年

    為什么阿里巴巴要求日期格式化時(shí)必須有使用y表示年

    這篇文章主要介紹了為什么阿里巴巴要求日期格式化時(shí)必須有使用y表示年,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • IDEA運(yùn)行SSM項(xiàng)目的超詳細(xì)圖解教程

    IDEA運(yùn)行SSM項(xiàng)目的超詳細(xì)圖解教程

    SSM項(xiàng)目部署其實(shí)很簡單,下面這篇文章主要給大家介紹了關(guān)于IDEA運(yùn)行SSM項(xiàng)目的超詳細(xì)圖解教程,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • Java微服務(wù)Nacos Config配置中心超詳細(xì)講解

    Java微服務(wù)Nacos Config配置中心超詳細(xì)講解

    配置文件相對(duì)分散。在一個(gè)微服務(wù)架構(gòu)下,配置文件會(huì)隨著微服務(wù)的增多變的越來越多,而且分散 在各個(gè)微服務(wù)中,不好統(tǒng)一配置和管理。每一個(gè)環(huán)境所使用的配置理論上都是不同的,一旦需要修改,就需要我們?nèi)ジ鱾€(gè)微服務(wù)下手動(dòng)維護(hù)
    2023-02-02

最新評(píng)論