最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于@ComponentScan注解及其XML配置方式

 更新時(shí)間:2023年09月22日 15:07:24   作者:kosamino  
這篇文章主要介紹了基于@ComponentScan注解及其XML配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

@ComponentScan注解及其XML配置

開發(fā)中會(huì)經(jīng)常使用包掃描,只要標(biāo)注了@Controller、@Service、@Repository,@Component 注解的類會(huì)自動(dòng)加入到容器中,ComponentScan有注解和xml配置兩種方式。

注解

@ComponentScan 包含過濾和排除過濾

  • ComponentScan.Filter[] includeFilters() default {}; 按照某些規(guī)則排除組件
  • ComponentScan.Filter[] excludeFilters() default {}; 指定掃描的時(shí)候只需要包含哪些組件
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
    @AliasFor("basePackages")
    String[] value() default {};
    @AliasFor("value")
    String[] basePackages() default {};
    Class<?>[] basePackageClasses() default {};
    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
    Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
    ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
    String resourcePattern() default "**/*.class";
    boolean useDefaultFilters() default true;
    ComponentScan.Filter[] includeFilters() default {};
    ComponentScan.Filter[] excludeFilters() default {};
    boolean lazyInit() default false;
    @Retention(RetentionPolicy.RUNTIME)
    @Target({})
    public @interface Filter {
        FilterType type() default FilterType.ANNOTATION;
        @AliasFor("classes")
        Class<?>[] value() default {};
        @AliasFor("value")
        Class<?>[] classes() default {};
        String[] pattern() default {};
    }
}

FilterType 指定不同的包含/排除規(guī)則:

package org.springframework.context.annotation;
public enum FilterType {
    ANNOTATION,
    ASSIGNABLE_TYPE,
    ASPECTJ,
    REGEX,
    CUSTOM;
    private FilterType() {
    }
}

1、Spring使用注解 包掃描 @ComponentScan

@ComponentScan("com.spring.annotation")
@Configuration
public class MainConfig {
}

注意:mainConfig 配置類也是一個(gè)組件 因?yàn)锧Configuration 注解中標(biāo)有@Component。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    String value() default "";
}

2、按照注解類型排除

例如排除以下類型:Controller.class, Service.class, Repository.class:

@ComponentScan(value = "com.spring.annotation", excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class, Repository.class})
})
@Configuration
public class MainConfig {
}

3、包含過濾includeFilters

如果想要只包含 Controller 注解的bean,如下配置:

@ComponentScan(value = "com.spring.annotation", includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,
                classes = {Controller.class})},useDefaultFilters = false)
@Configuration
public class MainConfig {
}

注意:需要添加 useDefaultFilters = false。

4、使用@ComponentScans 來指定掃描策略

ComponentScans 注解結(jié)構(gòu)如下:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
public @interface ComponentScans {
    ComponentScan[] value();
}

可以看到其內(nèi)部是一個(gè)ComponentScan[] 數(shù)組,所以我們可以在其中指定多個(gè)ComponentScan。

例如:

指定不同的類型,包含Controller 注解的bean 和 BookService類型的bean:

@ComponentScans(value = {
        @ComponentScan(value = "com.spring.annotation", includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class}),
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {BookService.class})
        },useDefaultFilters = false)
})
@Configuration
public class MainConfig {
}

5、FilterType.CUSTOM:使用自定義規(guī)則

1>. 編寫MyTypeFilter 并實(shí)現(xiàn) TypeFilter 接口;

2>. match方法中 實(shí)現(xiàn)自定義規(guī)則。

/**
 * 自定義過濾規(guī)則
 */
public class MyTypeFilter implements TypeFilter {
    /**
     *
     * @param metadataReader
     * @param metadataReaderFactory
     * @return
     * @throws IOException
     * metadataReader:讀取到的當(dāng)前正在掃描的類的信息
     * metadataReaderFactory:可以獲取到其他任何類信息的
     *
     *
     */
    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();
        System.out.println("--->"+className);
        if(className.contains("er")){
            return true;
        }
        return false;
    }
}

3>. 使用實(shí)例(當(dāng)前掃描到的類,類名中包含er,就會(huì)注入到容器中):

@ComponentScans(value = {
        @ComponentScan(value = "com.spring.annotation", includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class}),
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {BookService.class}),
                @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
        },useDefaultFilters = false)
})
@Configuration
public class MainConfig {
}

注解小結(jié):

  • @ComponentScan value:指定要掃描的包
  • excludeFilters = Filter[] :指定掃描的時(shí)候按照什么規(guī)則排除那些組件
  • includeFilters = Filter[] :指定掃描的時(shí)候只需要包含哪些組件
  • FilterType.ANNOTATION:按照注解
  • FilterType.ASSIGNABLE_TYPE:按照給定的類型;
  • FilterType.ASPECTJ:使用ASPECTJ表達(dá)式
  • FilterType.REGEX:使用正則指定
  • FilterType.CUSTOM:使用自定義規(guī)則

XML配置

我們使用component-scan來進(jìn)行bean的加載,例如,我們通常會(huì)使用如下的配置:

application.xml:

<context:component-scan base-package="com.cn.kvn.service,com.cn.kvn.config,com.baidu">
        <context:include-filter type="annotation" expression="com.alibaba.dubbo.config.annotation.Service" />
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

spring-servlet.xml:

<context:component-scan base-package="com.cn.kvn.controller" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

原理: componentScan解析bean的入口為:ComponentScanBeanDefinitionParser#parse(Element element, ParserContext parserContext)

@Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
        basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
        String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
                ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
        // Actually scan for bean definitions and register them.
        ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
        Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
        registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
        return null;
    }

base-package屬性告訴spring要掃描的包,use-default-filters="false"表示不要使用默認(rèn)的過濾器。

configureScanner會(huì)去配置scan時(shí)的使用的filter,其中use-default-filters屬性是來控制是否要使用默認(rèn)的過濾器的(默認(rèn)的過濾器會(huì)去解析base-package下的含有@Component注解的類作為bean,其中@Repository, @Service, and @Controller都是@Component的子注解,故,默認(rèn)的過濾器會(huì)將它們?nèi)拷馕龀蒪ean)。

原碼中的英文注釋:

ClassPathScanningCandidateComponentProvider#ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment)

useDefaultFilters whether to register the default filters for the @Component, @Repository, @Service, and @Controller stereotype annotations

用戶自定義的include-filter和exclude-filter會(huì)在以下方法中被解析加載。

ComponentScanBeanDefinitionParser#parseTypeFilters(Element element, ClassPathBeanDefinitionScanner scanner, ParserContext parserContext)

在執(zhí)行Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);的時(shí)候,使用過濾器的順序是,exclude-filter優(yōu)于include-filter。

也就是說,如果同時(shí)定義了exclude-filter排除了某類(某個(gè))bean,但是include-filter又將其包含了,則該bean不會(huì)被加載到spring容器。

ClassPathScanningCandidateComponentProvider.java
/**
     * Determine whether the given class does not match any exclude filter
     * and does match at least one include filter.
     * @param metadataReader the ASM ClassReader for the class
     * @return whether the class qualifies as a candidate component
     */
    protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
        for (TypeFilter tf : this.excludeFilters) {
            if (tf.match(metadataReader, this.metadataReaderFactory)) {
                return false;
            }
        }
        for (TypeFilter tf : this.includeFilters) {
            if (tf.match(metadataReader, this.metadataReaderFactory)) {
                return isConditionMatch(metadataReader);
            }
        }
        return false;
    }

附:過濾規(guī)則設(shè)置

filter標(biāo)簽的type和表達(dá)式說明如下:

Filter TypeExamples ExpressionDescriptioninclude-filter為例
annotationorg.example.SomeAnnotation符合SomeAnnoation的target class

<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>

表示掃描base-package下的類上加了Aspect注解的類,并注冊(cè)到spring的bean容器

assignableorg.example.SomeClass指定class或interface的全名

<context:include-filter type="assignable" expression="com.test.scan.StuService"/>

指定掃描StuService類作為bean

aspectjorg.example..*Service+AspectJ語(yǔ)法
regexorg\.example\.Default.*Regelar Expression
customorg.example.MyTypeFilterSpring3新增自訂Type,實(shí)作org.springframework.core.type.TypeFilter

注意:如果通過regex將filter的type設(shè)置成了正則表達(dá)式,注意在正則里面.表示所有字符,而\.才表示真正的.字符。例如我們的正則表示以Dao或者Service結(jié)束的類。

我們也可以使用annotaion來限定,如下:

<context:component-scan base-package="cn.outofmemory.spring" use-default-filters="false">
  <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> 
  <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> 
</context:component-scan>

總結(jié)

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

相關(guān)文章

  • JavaSwing后臺(tái)播放音樂mp3

    JavaSwing后臺(tái)播放音樂mp3

    這篇文章主要為大家詳細(xì)介紹了JavaSwing后臺(tái)播放音樂mp3,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Java8中Optional的一些常見錯(cuò)誤用法總結(jié)

    Java8中Optional的一些常見錯(cuò)誤用法總結(jié)

    我們知道 Java 8 增加了一些很有用的 API, 其中一個(gè)就是 Optional,下面這篇文章主要給大家介紹了關(guān)于Java8中Optional的一些常見錯(cuò)誤用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-07-07
  • 詳解java動(dòng)態(tài)代理模式

    詳解java動(dòng)態(tài)代理模式

    這篇文章主要為大家詳細(xì)介紹了java動(dòng)態(tài)代理模式,總結(jié)一下代理模式,以及jdk,cglib代理模式用法,來理解代理模式,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 企業(yè)級(jí)Kubernetes管理平臺(tái)Wayne功能特性介紹

    企業(yè)級(jí)Kubernetes管理平臺(tái)Wayne功能特性介紹

    這篇文章主要為大家介紹了企業(yè)級(jí)Kubernetes管理平臺(tái)Wayne的功能特性及架構(gòu)設(shè)計(jì),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • 使用@RequestBody配合@Valid校驗(yàn)入?yún)?shù)

    使用@RequestBody配合@Valid校驗(yàn)入?yún)?shù)

    這篇文章主要介紹了使用@RequestBody配合@Valid校驗(yàn)入?yún)?shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • J2SE與c#的幾點(diǎn)比較

    J2SE與c#的幾點(diǎn)比較

    這篇文章主要介紹了J2SE與c#的幾點(diǎn)比較,是看完馬士兵老師的J2SE視頻教程有感而寫,需要的朋友可以參考下
    2014-08-08
  • Java中使用BeanMap將對(duì)象轉(zhuǎn)為Map詳解

    Java中使用BeanMap將對(duì)象轉(zhuǎn)為Map詳解

    這篇文章主要介紹了Java中使用BeanMap將對(duì)象轉(zhuǎn)為Map詳解,BeanMap?是?Apache?Commons?BeanUtils?庫(kù)中的一個(gè)類,BeanMap?可以將?Java?對(duì)象的屬性作為鍵,屬性值作為對(duì)應(yīng)的值,存儲(chǔ)在一個(gè)?Map?中,它提供了一種將?Java?對(duì)象轉(zhuǎn)換為?Map?的方式,需要的朋友可以參考下
    2024-01-01
  • SpringBoot部署到Linux讀取resources下的文件及遇到的坑

    SpringBoot部署到Linux讀取resources下的文件及遇到的坑

    本文主要給大家介紹SpringBoot部署到Linux讀取resources下的文件,在平時(shí)業(yè)務(wù)開發(fā)過程中,很多朋友在獲取到文件內(nèi)容亂碼或者文件讀取不到的問題,今天給大家分享小編遇到的坑及處理方案,感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • Java實(shí)現(xiàn)簡(jiǎn)易畫圖板

    Java實(shí)現(xiàn)簡(jiǎn)易畫圖板

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)易畫圖板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 關(guān)于Java內(nèi)存訪問重排序的研究

    關(guān)于Java內(nèi)存訪問重排序的研究

    文章主要介紹了重排序現(xiàn)象及其在多線程編程中的影響,包括內(nèi)存可見性問題和Java內(nèi)存模型中對(duì)重排序的規(guī)則
    2025-01-01

最新評(píng)論

宝兴县| 酉阳| 左云县| 孙吴县| 宜阳县| 林州市| 博兴县| 久治县| 龙泉市| 台前县| 五指山市| 彭州市| 伽师县| 太保市| 新河县| 承德市| 台中市| 清河县| 项城市| 溧水县| 伊宁县| 花垣县| 如东县| 成都市| 泽普县| 通辽市| 方城县| 木里| 辛集市| 山阴县| 北票市| 舟山市| 秀山| 景谷| 洮南市| 定陶县| 曲沃县| 西宁市| 承德县| 安岳县| 恩施市|