日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

spring component-scan filter

發布時間:2024/4/13 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring component-scan filter 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

(參考的Spring version :?4.1.6.RELEASE)

我們通常會使用component-scan來進行bean的加載,但是它里面的實現機制卻是一知半解。根據原碼來理解一下,可能會更加清晰。

例如,我們通常會使用如下的配置:

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)
@Overridepublic 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"表示不要使用默認的過濾器

?

  • configureScanner會去配置scan時的使用的filter,其中use-default-filters屬性是來控制是否要使用默認的過濾器的。

(默認的過濾器會去解析base-package下的含有@Component注解的類作為bean,其中@Repository, @Service, and @Controller都是@Component的子注解,故,默認的過濾器會將它們全部解析成bean)

原碼中的英文注釋:(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會在ComponentScanBeanDefinitionParser#parseTypeFilters(Element element, ClassPathBeanDefinitionScanner scanner, ParserContext parserContext)方法中被解析加載。

?

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

也就是說,如果同時定義了exclude-filter排除了某類(某個)bean,但是include-filter又將其包含了,則該bean不會被加載到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;}

?

附:過濾規則設置

context:component-scan節點允許有兩個子節點<context:include-filter>和<context:exclude-filter>。filter標簽的type和表達式說明如下:

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

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

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

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

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

指定掃描StuService類作為bean

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

?

在我們的示例中,將filter的type設置成了正則表達式,regex,注意在正則里面.表示所有字符,而\.才表示真正的.字符。我們的正則表示以Dao或者Service結束的類。

我們也可以使用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>

?這里我們指定的include-filter的type是annotation,expression則是注解類的全名。

另外context:conponent-scan節點還有<context:exclude-filter>可以用來指定要排除的類,其用法和include-filter一致。

總結

以上是生活随笔為你收集整理的spring component-scan filter的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。