Spring-掃描注解原理,注解自動掃描原理分析


 

注解自動掃描原理分析

 

在spring的配置文件中加入如下代碼,spring便開啟了自動掃描,那么它的底層到底是如何實現的呢?

<context:component-scan base-package="com.wisely.highlight_spring4.ch1"/>

 

  1. 首先找到解析這個標簽的地方,spring 中解析具體的標簽都有相應的解析器,且都繼承了NamespaceHandlerSupport
    在這里插入圖片描述
    在這里插入圖片描述

  2. 查看 ComponentScanBeanDefinitionParserparse方法
    在這里插入圖片描述

  3. 真正的邏輯其實是在ClassPathBeanDefinitionScannerdoScan方法中
    在這里插入圖片描述

  4. 測試一下掃描過程

 1 package com.wisely.highlight_spring4.ch1.di;
 2 
 3 import java.io.IOException;
 4 import java.util.LinkedHashSet;
 5 import java.util.Set;
 6 
 7 import org.springframework.beans.factory.config.BeanDefinition;
 8 import org.springframework.context.annotation.ScannedGenericBeanDefinition;
 9 import org.springframework.core.io.Resource;
10 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
11 import org.springframework.core.io.support.ResourcePatternResolver;
12 import org.springframework.core.type.classreading.MetadataReader;
13 import org.springframework.core.type.classreading.MetadataReaderFactory;
14 import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
15 import org.springframework.stereotype.Component;
16 import org.springframework.stereotype.Controller;
17 import org.springframework.stereotype.Service;
18 
19 public class BeanFactoryTest
20 {
21     public static void main(String[] args) throws IOException, ClassNotFoundException {
22         Set<BeanDefinition> candidates = new LinkedHashSet<>();
23 
24         ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();  
25         //這里特別注意一下類路徑必須這樣寫
26         //獲取指定包下的所有類
27         Resource[] resources = resourcePatternResolver.getResources("classpath*:com\\wisely\\highlight_spring4\\ch1\\di\\*");  
28          
29         MetadataReaderFactory metadata=new SimpleMetadataReaderFactory();
30         for(Resource resource:resources) {
31             System.out.println(resource);
32             MetadataReader metadataReader=metadata.getMetadataReader(resource);
33             ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
34             sbd.setResource(resource);
35             sbd.setSource(resource);
36             candidates.add(sbd);
37         }
38         for(BeanDefinition beanDefinition : candidates) {  
39             String classname=beanDefinition.getBeanClassName();
40             //掃描controller注解
41             Controller c=Class.forName(classname).getAnnotation(Controller.class);
42             //掃描Service注解
43             Service s=Class.forName(classname).getAnnotation(Service.class);
44             //掃描Component注解
45             Component component=Class.forName(classname).getAnnotation(Component.class);
46             if(c!=null ||s!=null ||component!=null){       
47                 System.out.println(classname);
48             }
49         } 
50     }
51 }
View Code

 

  1. 我的項目包結構
    在這里插入圖片描述

  2. 控制台輸出結果
    在這里插入圖片描述

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM