Spring源碼分析

本文采用的Spring版本是5.1.1spring

1. AnnotationConfigApplicationContext

首先咱們採用Spring官方推薦的JavaConfig風格+註解的方式來初始化Spring:緩存

// 配置類
@Configuration
@ComponentScan(basePackages = {"com.demo.learn.service"})
public class AppConfig {
}

// 入口類
public static void main(String[] args) {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
    DemoServiceImpl serviceImpl =  (DemoServiceImpl)applicationContext.getBean(DemoServiceImpl.class);
    System.out.println(serviceImpl);
}
複製代碼

1.1 進入AnnotationConfigApplicationContext的構造方法

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    // 調用自身無參構造方法 -> 1.2
	this();
	register(annotatedClasses);
	refresh();
}
複製代碼

1.2 點擊this()進入無參構造方法,

AnnotationConfigApplicationContext繼承了GenericApplicationContext因此此處隱式調用了父類的無參構造方法建立了一個Bean工廠:DefaultListableBeanFactorybash

GenericApplicationContext實現了BeanDefinitionRegistry接口,而AnnotationConfigApplicationContext繼承了GenericApplicationContext,因此AnnotationConfigApplicationContext就是一個registryapp

BeanDefinitionRegistry 是一個接口,定義了關於 BeanDefinition 的註冊、移除、查詢等一系列的操做。該接口有三個實現類:DefaultListableBeanFactory、GenericApplicationContext、SimpleBeanDefinitionRegistry,其中 GenericApplicationContext 底層調用的是 DefaultListableBeanFactory 中的實現方法,因此嚴格意義上來講,只有兩個實現類。ide

public GenericApplicationContext() {
	this.beanFactory = new DefaultListableBeanFactory();
}
複製代碼

此處初始化了一個讀取器和一個掃描器post

// 註解形式bean的讀取器
private final AnnotatedBeanDefinitionReader reader;

// ... 
public AnnotationConfigApplicationContext() {
    // 給註冊表建立一個bean讀取器
    // 初始化一個DefaultListableBeanFactory -> 1.3
	this.reader = new AnnotatedBeanDefinitionReader(this);
	//scanner的用處不是很大,它僅僅是在咱們外部手動調用 .scan 等方法纔有用,常規方式是不會用到scanner對象的
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}
複製代碼

1.3 進入this.reader = new AnnotatedBeanDefinitionReader(this);一路點下去,咱們會看到一系列初始化過程

public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,
		@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {

	this.registry = registry;
	this.beanFactory = deduceBeanFactory(registry);
	this.environment = (environment != null ? environment : deduceEnvironment(registry));
	this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));
	this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);
}
複製代碼

1.4 初始化DefaultListableBeanFactory並註冊各類Processor

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
		BeanDefinitionRegistry registry, @Nullable Object source) {
    // 建立beanFactory
	DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
	if (beanFactory != null) {
		if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
			beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
		}
		if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
			beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
		}
	}

	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

	if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
	}
    // ...
}
複製代碼

BeanDefinition是什麼,顧名思義,它是用來描述Bean的,裏面存放着關於Bean的一系列信息,好比Bean的做用域,Bean所對應的Class,是否懶加載,是否Primary等等,這個BeanDefinition也至關重要ui

1.5 進入DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);

在此以前registry爲AnnotationConfigApplicationContext,根據1.2得知是GenericApplicationContext的子類,執行1.5.1處代碼this

@Nullable
private static DefaultListableBeanFactory unwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry) {
	if (registry instanceof DefaultListableBeanFactory) {
		return (DefaultListableBeanFactory) registry;
	}
	// 1.5.1
	else if (registry instanceof GenericApplicationContext) {
		return ((GenericApplicationContext) registry).getDefaultListableBeanFactory();
	}
	else {
		return null;
	}
}
複製代碼

1.5.2 進入1.5.1代碼塊,能夠看到,返回的是GenericApplicationContextbeanFactorybeanFactory在1.2的時候已經被賦值爲DefaultListableBeanFactory

public final DefaultListableBeanFactory getDefaultListableBeanFactory() {
	return this.beanFactory;
}
複製代碼

1.6 上面方法中有一個registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)方法,咱們點進去能夠看到這個方法中給RootBeanDefinition設置了一個角色BeanDefinition.ROLE_INFRASTRUCTURE, 此角色表名用此方法註冊的bean徹底是spring的內部bean,與最終用戶無關

1.6.1 角色

  • 0: 用戶自定義的Bean
  • 1:來源於配置文件的Bean
  • 2:Spring內部的Bean
private static BeanDefinitionHolder registerPostProcessor(
		BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

	definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	registry.registerBeanDefinition(beanName, definition);
	return new BeanDefinitionHolder(definition, beanName);
}
複製代碼

1.7 點擊進入registry.registerBeanDefinition(beanName, definition)方法

能夠看到這個方法是一個接口,先來看下此接口都有哪些方法spa

public interface BeanDefinitionRegistry extends AliasRegistry {
    // 註冊BeanDefinition
    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;
    // 移除BeanDefinition
    void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
    // 獲取BeanDefinition
    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
    // 根據bean name判斷是否存在BeanDefinition
    boolean containsBeanDefinition(String beanName);
    // 獲取全部的BeanDefinition
    String[] getBeanDefinitionNames();
    // 獲取BeanDefinition數量
    int getBeanDefinitionCount();
    // 判斷bean name是否被佔用
    boolean isBeanNameInUse(String beanName);
}
複製代碼

此時咱們須要找它的實現類(由1.5.2得知爲DefaultListableBeanFactory)debug

這個類就是咱們的Bean容器所在的位置

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
複製代碼
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

    // 存儲全部的BeanDefinition,key就是bean name,這個Map就是咱們一直所說的Bean容器
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
    // 存儲全部的bean name
    private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
    
    /**
     * 註冊bean
     * @param beanName          bean name
     * @param BeanDefinition    bean對應的BeanDefinition
     */
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    		throws BeanDefinitionStoreException {
    
    	Assert.hasText(beanName, "Bean name must not be empty");
    	Assert.notNull(beanDefinition, "BeanDefinition must not be null");
    
    	if (beanDefinition instanceof AbstractBeanDefinition) {
    		try {
    		     // 驗證:
    		        1. 驗證是否重寫了方法
    		        2. 若是重寫了方法,經過beanName獲取方法,若是爲0則方法不存在,拋出異常,爲1則設置overload屬性爲false
    			((AbstractBeanDefinition) beanDefinition).validate();
    		}
    		catch (BeanDefinitionValidationException ex) {
    			throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
    					"Validation of bean definition failed", ex);
    		}
    	}
    
        // 從bean容器(beanDefinitionMap)中經過beanName獲取beanDefinition
    	BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    	if (existingDefinition != null) {
    	    // 判斷是否容許重寫beanDefinition,不容許則拋出異常
    		if (!isAllowBeanDefinitionOverriding()) {
    			throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
    		}
    		// 當原beanDefinition的角色小於新的beanDefinition角色時,輸出warn日誌,提示beanDefinition被覆蓋
    		else if (existingDefinition.getRole() < beanDefinition.getRole()) {
    			// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
    			if (logger.isInfoEnabled()) {
    				logger.info("Overriding user-defined bean definition for bean '" + beanName +
    						"' with a framework-generated bean definition: replacing [" +
    						existingDefinition + "] with [" + beanDefinition + "]");
    			}
    		}
    		// 當新beanDefinition的屬性值不等於原beanDefinition的屬性值時,輸出info提示beanDefinition被覆蓋
    		else if (!beanDefinition.equals(existingDefinition)) {
    			if (logger.isDebugEnabled()) {
    				logger.debug("Overriding bean definition for bean '" + beanName +
    						"' with a different definition: replacing [" + existingDefinition +
    						"] with [" + beanDefinition + "]");
    			}
    		}
    		else {
    			if (logger.isTraceEnabled()) {
    				logger.trace("Overriding bean definition for bean '" + beanName +
    						"' with an equivalent definition: replacing [" + existingDefinition +
    						"] with [" + beanDefinition + "]");
    			}
    		}
    		// 添加至bean容器,並覆蓋原beanDefinition
    		this.beanDefinitionMap.put(beanName, beanDefinition);
    	} 
    	// 容器中無對應的beanDefinition則直接註冊
    	else {
    	    // 判斷此工廠bean建立流程是否已經開始
    		if (hasBeanCreationStarted()) {
    			// Cannot modify startup-time collection elements anymore (for stable iteration)
    			synchronized (this.beanDefinitionMap) {
    			    // 添加beanDefinition至bean容器
    				this.beanDefinitionMap.put(beanName, beanDefinition);
    				// 建立新的beanNames集合,並將已經存在的beanNames放入該集合
    				List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
    				updatedDefinitions.addAll(this.beanDefinitionNames);
    				updatedDefinitions.add(beanName);
    				this.beanDefinitionNames = updatedDefinitions;
    				// 在手動建立bean的集合中,若是存在同名的beanName,則將集合中已經存的beanName移除
    				if (this.manualSingletonNames.contains(beanName)) {
    					Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
    					updatedSingletons.remove(beanName);
    					this.manualSingletonNames = updatedSingletons;
    				}
    			}
    		}
    		else {
    			// Still in startup registration phase
    			// 將當前bean對應的beanDefinition放入容器中
    			this.beanDefinitionMap.put(beanName, beanDefinition);
    			// 將當前beanName放入beanDefinitionNames中
    			this.beanDefinitionNames.add(beanName);
    			// 刪除同名的beanName
    			this.manualSingletonNames.remove(beanName);
    		}
    		// 將保存凍結beanDefinition的Map設爲null
    		this.frozenBeanDefinitionNames = null;
    	}
    
        // 若是當前註冊的beanDefinition已經存在,或者在(緩存單例bean實例map)中存在
    	if (existingDefinition != null || containsSingleton(beanName)) {
    	    // 重置給定bean的全部bean定義緩存,包括從其派生的bean的緩存
    		resetBeanDefinition(beanName);
    	}
    }
}
複製代碼

參考 juejin.im/post/5c637d…

相關文章
相關標籤/搜索