Spring源碼系列(一):refresh()方法

一、Spring容器入口

Spring通過應(yīng)用上下文(Application Context)來行使容器的工作。Spring自帶了多種類型的應(yīng)用上下文實現(xiàn),每種都以具體的類表示。下面是常用的幾個:

AnnotationConfigApplicationContext :從Java配置類中加載Spring應(yīng)用上下文。
AnnotationConfigWebApplicationContext :從Java配置類中加載Spring Web應(yīng)用上下文。
ClassPathXmlApplicationContext :從ClassPath下的XML配置文件中加載Spring應(yīng)用上下文。
FileSystemXmlApplicationContext :從文件系統(tǒng)的XML配置文件中加載Spring應(yīng)用上下文。
XmlWebApplicationContext :從Web應(yīng)用中的XML配置文件中加載Spring Web應(yīng)用上下文。

本文采用的ClassPathXmlApplicationContext來作為Spring容器的入口。

二、Spring源碼重要方法——refresh()方法

我們調(diào)試進(jìn)入ClassPathXmlApplicationContext類中,找到重要的方法refresh()。如下圖:

image.png

refresh():

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

三、準(zhǔn)備工作

Teacher類

public class Teacher {

    private String teacherId;

    private String teacherName;

    private Student student;

    public void setTeacherId(String teacherId) {
        this.teacherId = teacherId;
    }

    public void setTeacherName(String teacherName) {
        this.teacherName = teacherName;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public void print(){
        System.out.println("This is a teacher with teacherId: "+teacherId);
    }
}

Student類

public class Student {

    private String studentId;

    private String studentName;

    public void setStudentId(String studentId) {
        this.studentId = studentId;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }
}

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean id="teacher" class="com.zcs.mytest.xmlSetter.Teacher">
    <property name="teacherId" value="t001"/>
    <property name="teacherName" value="teacher001"/>
      <property name="student" ref="student"/>
  </bean>

    <bean id="student" class="com.zcs.mytest.xmlSetter.Student">
        <property name="studentId" value="s001"/>
        <property name="studentName" value="student001"/>
    </bean>
</beans>

測試類

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

    public static void main(String[] args) {
        //獲取容器對象
        ApplicationContext context=new ClassPathXmlApplicationContext("application-xmlsetter.xml");

        Teacher teacher = (Teacher) context.getBean("teacher");

        teacher.print();
    }

}

在之后的文章中,我們詳細(xì)分析其中一些重要的步驟。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容