spring-ioc(一)

不要問我閱讀spring源碼有什麼用,問就是沒有用,只是讓我本身使用spring的過程當中自信點!java

相關文章

spring-相關文章spring

說明

  1. 本文只對的是註解形式 AnnotationConfigApplicationContext
  2. 通常公司在使用的springmvc項目都是xml形式的
  3. springboot是使用的Annotation,可是咱們不會講springboot,等spring-ioc講完了再去說springboot
  4. 咱們是作測試,不是針對正常項目啓動的,也就是 new AnnotationConfigApplicationContext(MyConfig.class);
  5. spring-ioc東西特別的多,因此雖然我看了挺久的源碼了,可是我也是在學習的過程
  6. 目前沒有給spring-ioc作分幾篇文章的規劃,由於我感受就算規劃了也不是很準,有不少地方我本身也是卡住的狀態
  7. 學習spring要對java反射,動態代理有所瞭解

使用AnnotationConfigApplicationContext

先看段代碼json

public static void main(String[] args) {
        //建立spring beanFactory 這裏面就是咱們常說的 spring-ioc的初始化 spring的核心之一
	AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);
	//這個getBena 重要,屬於spring初始化的過程,建立bean的實例,上面的代碼只是把beanDefinition(bean的描述)放入對應的容器(就是個map),這句代碼纔是實例化
	TestController tc = ac.getBean(TestController.class);
	tc.jsontest("帥哥", 13);
}

@Configuration
@ComponentScan(value= "com.kiss.mxb")
public class MyConfig {
    //這是個配置類,標記了掃面的包
}
複製代碼

部分源碼

下面去看看new AnnotationConfigApplicationContext(MyConfig.class) 究竟作了什麼東西springboot

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    //調用無參構造器(本文的主要內容)
	this();
	//註冊咱們傳進來的這個配置類
	register(annotatedClasses);
	//這個忒別特別的重要
	refresh();
}
複製代碼

無參構造器mvc

public AnnotationConfigApplicationContext() {
    //這裏,建立讀取器,其實裏面主要的就是先註冊幾個 beanDefinition
	this.reader = new AnnotatedBeanDefinitionReader(this);
	//咋一看是和包的掃描有關係,可是後面你會發現沒用到,我也不知道還有別的用
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}
複製代碼

讀取器的構造方法post

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	Assert.notNull(environment, "Environment must not be null");
	//賦值一個註冊器,這個註冊器的功能就是把 beanDefinition 放入map
	//這個註冊器其實就是beanFactory 自己,你能夠看下AnnotationConfigApplicationContext 的頂層接口有一個就是 BeanDefinitionRegistry
	this.registry = registry;
	this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
	//這個裏面就是上面提到的註冊幾個beanDefinition,方法的參數爲註冊器,說明這幾個beanDefinition是spring本身定義的bean
	//還有就是 註冊這個詞,聽上去高大上,其實就是把一寫數據放入一些map的過程
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
複製代碼

只看咱們這個文章須要的代碼,其他代碼省略學習

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) {
    //獲取bean工廠
	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);
        //這裏 本文的重點,,也是貫穿spring-ioc的重點
        //主要是想spring註冊一個bean工廠的後置處理器
	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));
	}
      //這個是註冊了一個bean的後置處理器,這個後置處理器還想是在依賴注入的時候使用的
	if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	................................................................................................
	return beanDefs;
}
複製代碼
private static BeanDefinitionHolder registerPostProcessor( BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

	definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	//註冊的代碼就是這句,今天不說了之後會講
	registry.registerBeanDefinition(beanName, definition);
	return new BeanDefinitionHolder(definition, beanName);
}
複製代碼

至於什麼是bean的後置處理器和bean工廠的後置處理器,我會單獨的章節介紹其用法.測試

總結

  1. 重要就是說了下無參構造器中註冊了幾個spring內部的bean
  2. 其中ConfigurationClassPostProcessor 這個bean工廠的後置處理器特別的重要
相關文章
相關標籤/搜索