小白Spring源碼解讀 —— (一)

當你的才華還撐不起你的野心的時候,唯有靜下心來學習。
1. 簡介

       在研究spring源碼之前,首先要確保自身有使用過spring框架開發過項目,有一定的基礎知識,比如知道什麼是beanFactory、Ioc、依賴注入等,並且簡單知道原理最好。由於spring源碼體系龐大,無法做到涉及到每一個方面細節,只能講解他的核心功能,一個章節也無法全部概述,可能會分多個章節。在讀spring源碼的過程中,如果只是單純的看並不會有太大的收穫,還是需要自己手動調式源碼。本章是基於註解方式(AnnotationConfigApplicationContext)進行解讀的。編寫測試用例來模擬spring加載流程,當了解了spring的工作流程在談他的如何進行融會貫的。
       一定要自己對着源碼讀,切記在讀源碼的過程中,不要死扣細節,要使用面向對象的思想來解讀,只需要知道這段代碼爲我們做了什麼就可以了,如果想深入瞭解,可以自己點進去深入研究,要不然代碼段太長,容易繞暈不容易讀下去。
       以一個項目爲例,看spring是如何進行工作的,結構如下,隨便使用一個spring項目就可以,並沒有太大影響:
在這裏插入圖片描述
       編寫一個測試類,進行spring加載:

@ComponentScan("com.online.manager")
public class AppController {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppController.class);
        // TODO1 到這一步spring已經加載完成
        UserController userController = context.getBean(UserController.class);
    }
}

       當測試執行到context.getBean的時候,spring容器已經加載完成了,所有我們需要查看new AnnotationConfigApplicationContext底層做了什麼。當點擊進入到AnnotationConfigApplicationContext類中(ctrl + 鼠標)的時候,我們進入的是這個構造方法:

	public AnnotationConfigApplicationContext(Class... annotatedClasses) {
        // this 是調用自身的無參構造方法, 點進行查看
        // 本章節只講這個this做了什麼,不要看他簡單,其實很深
        this();
        // 下一次講
        this.register(annotatedClasses);
        this.refresh();
    }

       可以看見第一行代碼this();他調用的是自身的無參構造方法,由於java特性知道在調用自身的無參構造方法,會先調用父類的無參構造方法,所以我們先進入他的父類(GenericApplicationContext)中查看他的無參構造。

       GenericApplicationContext無參構造方法:

	// 父類的這個屬性非常重要,他就是spring的工廠
	private final DefaultListableBeanFactory beanFactory;
	public GenericApplicationContext() {
        this.customClassLoader = false;
        this.refreshed = new AtomicBoolean();
        // 在父類構造方法中初始化工廠 (很重要)
        this.beanFactory = new DefaultListableBeanFactory();
    }

       在GenericApplicationContext的類中,可以看到他有一個非常重要的屬性,就是我們常說的bean工廠beanFactory,想看他的屬性自己點進去查看,查看他有哪些屬性。他的構造方法爲我們的bean工廠進行實例化了spring工廠(只是創建但並沒有初始化)。這就是beanFactory的真身,如果想深入瞭解可以繼續查找GenericApplicationContext的父類爲我們做了什麼工作,這裏就不在概述了。

       基於繼承關係,AnnotationConfigApplicationContext類持有了這個beanFactory的實例,很重要。父類的構造方法執行完了,接下來看自己的構造方法。(不要繞暈了)

        AnnotationConfigApplicationContext無參構造方法:

	public AnnotationConfigApplicationContext() {
		// 把自身的實例傳遞給他的構造方法,創建了一個註解bean定義讀取器,用來把我們的配置類解析成BeanDefinition。很重要
        this.reader = new AnnotatedBeanDefinitionReader(this);
        // 創建一個bean定義掃描器,在外部手動調用的,使用scan方法進行掃描,不重要可調過
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

      AnnotationConfigApplicationContext的構造方法通過把自身實例(this)傳過去調用AnnotatedBeanDefinitionReader的構造方法創建一個註解bean定義讀取器,作用用來把我們的配置類解析成BeanDefinition放入到beanFactory的beanDefinitionMap屬性中。

       爲什麼要報this傳過去呢?可以思考一下?
       因爲這個this是AnnotationConfigApplicationContext的實例,而因爲他父類的關係,所以他自己持有了bean工廠的實例。因此可以通過過來的this獲取到我們的beanFactory工廠。

       但是在AnnotatedBeanDefinitionReader(this)的這個構造方法裏幫我們做了很多的事情,這裏面代碼非常的重要,主要是完成beanFactory工廠的首次初始化工作,往下看。

       AnnotatedBeanDefinitionReader(this)構造方法:

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
        this(registry, getOrCreateEnvironment(registry));
    }
	// 最終調用的構造方法
    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
        ..... 不太重要的代碼省略, 主要完成初始化
        // 很重要 -- 完成`beanFactory`工廠的首次初始化工作
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }

       可以看到上面的這個BeanDefinitionRegistry registry參數的實際上就是我們的AnnotationConfigApplicationContext實現(可以通過查看類關係,AnnotationConfigApplicationContextBeanDefinitionRegistry的一種實現),最終會調用registerAnnotationConfigProcessors這個方法。

       registerAnnotationConfigProcessors方法(很重要):

	public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
        registerAnnotationConfigProcessors(registry, (Object)null);
    }
	// 最終調用這個方法
    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
        // 在這個方法裏,從registry裏獲取我們的bean工廠,細節可以自己點進去查看(ctrl + 點擊方法)
        // 實現是 把registry強轉爲GenericApplicationContext,調用他的getDefaultListableBeanFactory獲取工廠
        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        // 在之前工廠就已經創建好了,肯定不爲空
        // 下面代碼就是bean工廠的初始化工作了,只需要知道爲我們工廠填充了這些屬性,爲了之後使用這些功能
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            	// 添加了比較器用於排序,(處理Ordered接口、PriorityOrdered接口功能)
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }

            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            // 提供延遲加載的功能
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(8);
        RootBeanDefinition def;
        // 向工廠註冊的7個後置處理器非常重要也是完成spring的核心功能
        if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {
            def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            // 向beanDefinitionMap加入ConfigurationClassPostProcessor後置處理器
            // 他實現的是BeanDefinitionRegistryPostProcessor接口
            // 主要完成自定義類(@Configuration、@Componet、@Serveice、@Import註解)的掃描,把我們定義的類加入到spring容器中
            // 後面會在使用的時候會詳細介紹
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
        }

        if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) {
            def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            // 向beanDefinitionMap加入AutowiredAnnotationBeanPostProcessor後置處理器
            // 他實現的是BeanFactoryPostProcessor接口, 處理@Autowired,完成bean的屬性注入的工作
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));
        }

        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			// 向beanDefinitionMap加入CommonAnnotationBeanPostProcessor後置處理器
            // 他實現的是BeanFactoryPostProcessor接口, 處理@Resource和JSR 250註解
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		//jpa功能
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
	
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			// 注入事件監聽方法
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			// 注入默認事件監聽工廠
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}
        return beanDefs;
    }

       registerAnnotationConfigProcessors這個方法很重要,完成beanFactory的初始化工作,向beanDefinitionMap中註冊了7個後置處理器的BeanDefinition的信息,其中ConfigurationClassPostProcessorAutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor這三個後置處理器非常的重要,其中ConfigurationClassPostProcessor這個後置處理器是重中之重,後續使用的時候會進行講解,這是隻是想beanFactory中進行設置,但並沒有使用,方便在後續時候過程中不知道他是如何產生的。

       到這裏AnnotationConfigApplicationContext的無參構造方法裏的new AnnotatedBeanDefinitionReader(this)這行代碼就執行結束了。該執行new ClassPathBeanDefinitionScanner(this)這段代碼了,其實這段代碼的用處不是很大,主要是提供外部也就是程序員自己在外部使用的,不重要,感興趣的話可以自己點進去查看。

       到這裏AnnotationConfigApplicationContext的構造方法裏的this()方法就執行結束了,其中有很多細節的地方沒有講述清楚,可以的話可以自己進行查看。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章