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

一、Spring容器入口

Spring通过应用上下文(Application Context)来行使容器的工作。Spring自带了多种类型的应用上下文实现,每种都以具体的类表示。下面是常用的几个:

AnnotationConfigApplicationContext :从Java配置类中加载Spring应用上下文。
AnnotationConfigWebApplicationContext :从Java配置类中加载Spring Web应用上下文。
ClassPathXmlApplicationContext :从ClassPath下的XML配置文件中加载Spring应用上下文。
FileSystemXmlApplicationContext :从文件系统的XML配置文件中加载Spring应用上下文。
XmlWebApplicationContext :从Web应用中的XML配置文件中加载Spring Web应用上下文。

本文采用的ClassPathXmlApplicationContext来作为Spring容器的入口。

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

我们调试进入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();
            }
        }
    }

三、准备工作

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();
    }

}

在之后的文章中,我们详细分析其中一些重要的步骤。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容