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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

ClassPathScanningCandidateComponentProvider 扫描给定包及其子包的类

發布時間:2024/4/13 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ClassPathScanningCandidateComponentProvider 扫描给定包及其子包的类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ClassPathScanningCandidateComponentProvider 類的findCandidateComponents()方法具體實現掃描給定類路徑包的功能,主要源碼如下:

//保存過濾規則要包含的注解,即Spring默認的@Component、@Repository、@Service、 //@Controller注解的Bean,以及JavaEE6的@ManagedBean和JSR-330的@Named注解 private final List<TypeFilter> includeFilters = new LinkedList<>();//保存過濾規則要排除的注解 private final List<TypeFilter> excludeFilters = new LinkedList<>(); //構造方法,該方法在子類ClassPathBeanDefinitionScanner的構造方法中被調用 public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters) {this(useDefaultFilters, new StandardEnvironment()); }public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) {//如果使用Spring默認的過濾規則,則向容器注冊過濾規則if (useDefaultFilters) {registerDefaultFilters();}setEnvironment(environment);setResourceLoader(null); } //向容器注冊過濾規則 @SuppressWarnings("unchecked") protected void registerDefaultFilters() {//向要包含的過濾規則中添加@Component注解類,注意Spring中@Repository//@Service和@Controller都是Component,因為這些注解都添加了@Component注解this.includeFilters.add(new AnnotationTypeFilter(Component.class));//獲取當前類的類加載器ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();try {//向要包含的過濾規則添加JavaEE6的@ManagedBean注解this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.}try {//向要包含的過濾規則添加@Named注解this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.} } //掃描給定類路徑的包 public Set<BeanDefinition> findCandidateComponents(String basePackage) {if (this.componentsIndex != null && indexSupportsIncludeFilters()) {return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);}else {return scanCandidateComponents(basePackage);} } private Set<BeanDefinition> addCandidateComponentsFromIndex(CandidateComponentsIndex index, String basePackage) {//創建存儲掃描到的類的集合Set<BeanDefinition> candidates = new LinkedHashSet<>();try {Set<String> types = new HashSet<>();for (TypeFilter filter : this.includeFilters) {String stereotype = extractStereotype(filter);if (stereotype == null) {throw new IllegalArgumentException("Failed to extract stereotype from "+ filter);}types.addAll(index.getCandidateTypes(basePackage, stereotype));}boolean traceEnabled = logger.isTraceEnabled();boolean debugEnabled = logger.isDebugEnabled();for (String type : types) {//為指定資源獲取元數據讀取器,元信息讀取器通過匯編(ASM)讀//取資源元信息MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(type);//如果掃描到的類符合容器配置的過濾規則if (isCandidateComponent(metadataReader)) {//通過匯編(ASM)讀取資源字節碼中的Bean定義元信息AnnotatedGenericBeanDefinition sbd = new AnnotatedGenericBeanDefinition(metadataReader.getAnnotationMetadata());if (isCandidateComponent(sbd)) {if (debugEnabled) {logger.debug("Using candidate component class from index: " + type);}candidates.add(sbd);}else {if (debugEnabled) {logger.debug("Ignored because not a concrete top-level class: " + type);}}}else {if (traceEnabled) {logger.trace("Ignored because matching an exclude filter: " + type);}}}}catch (IOException ex) {throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);}return candidates; } //判斷元信息讀取器讀取的類是否符合容器定義的注解過濾規則 protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {//如果讀取的類的注解在排除注解過濾規則中,返回falsefor (TypeFilter tf : this.excludeFilters) {if (tf.match(metadataReader, getMetadataReaderFactory())) {return false;}}//如果讀取的類的注解在包含的注解的過濾規則中,則返回turefor (TypeFilter tf : this.includeFilters) {if (tf.match(metadataReader, getMetadataReaderFactory())) {return isConditionMatch(metadataReader);}}//如果讀取的類的注解既不在排除規則,也不在包含規則中,則返回falsereturn false; }

?

總結

以上是生活随笔為你收集整理的ClassPathScanningCandidateComponentProvider 扫描给定包及其子包的类的全部內容,希望文章能夠幫你解決所遇到的問題。

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