spring 启动过程分析

简述: spring是一个轻量级框架,目的是为了减少业务代码和其他层之间的耦合,有两个核心特性是IOC、AOP。spring能够很好支持这些功能,在启动的过程中做了哪些准备工作呢?本文主要介绍spring启动的过程以及为后续功能的实现做了哪些准备工作。

创建一个spring项目,如何启动程序呢?下面我们来看下启动的示例代码

public class SpringApplication {
//以注解应用上下文为例,下面的程序我们能从容器中获取一个Bean
    public static void main(String[] args) {
    // 容器启动的过程,在AnnotationConfigApplicationContext 创建的过程中
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConffig.class);
        Person person = (Person) applicationContext.getBean("person");
        System.out.println(person);
    }
}
//继承了GenericApplicationContext 
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry 
//从父类的无参构造器中可以看到创建了一个Bean工厂 DefaultListableBeanFactory
    public GenericApplicationContext() {
        this.customClassLoader = false;
        this.refreshed = new AtomicBoolean();
        this.beanFactory = new DefaultListableBeanFactory();
    }
 //我们再来看看AnnotationConfigApplicationContext的构造器
  public AnnotationConfigApplicationContext(Class... componentClasses) {
  //调用无参构造器,创建了一个读取器AnnotatedBeanDefinitionReader和扫描器ClassPathBeanDefinitionScanner
        this();
        //解析配置类为BeanDefinition并放入BeanDefinitionMap中
        this.register(componentClasses);
        //刷新启动容器
        this.refresh();
    }

在容器启动之前创建了bean工厂、bean定义的读取器和扫描器,下面主要来看下启动的方法 refresh做了哪些事情

 public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
        	//启动前容器的准备
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            //设置 Bean工厂的一些属性值
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                //执行Bean工厂的后置处理器,这个过程中会扫描类,将解析的Bean定义注册到bean工厂中
                this.invokeBeanFactoryPostProcessors(beanFactory);
                //实例化扫描到的beanPostProcessor,并赋值到bean工厂中
                this.registerBeanPostProcessors(beanFactory);
                //支持国际化相关的逻辑
                this.initMessageSource();
                //初始化多播器,默认是SimpleApplicationEventMulticaster
                this.initApplicationEventMulticaster();
                this.onRefresh();
                //将定义的监听器设置到ApplicationContext中,并执行之前的发布事件
                this.registerListeners();
                //实例化所有非懒加载的Bean
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

容器启动前的准备的工作

 protected void prepareRefresh() {
        ...
		//源码没有复制全,省略了一些非关键性部分
		...
        this.initPropertySources();
        //校验 一些必备 环境参数是否配置
        this.getEnvironment().validateRequiredProperties();
        if (this.earlyApplicationListeners == null) {
        //设置 早期的监听器
            this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
        } else {
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }

        this.earlyApplicationEvents = new LinkedHashSet();
    }

总结:通过上面代码的分析,我们对于spring启动的过程有了一定的了解,对于这部分内容总结如下:
1.在AnnotationConfigApplicationContext初始化前会初始化父类GenericApplicationContext,在其无参构造器中创建了Bean工厂DefaultListableBeanFactory。
2.调用自身的无参构造器,初始化bean定义的读取器和扫描器
3.调用refresh方法,来启动容器
*容器启动过程的总结
4.容器启动前的准备工作,例如 设置参数到Environment中,校验一些属性值是否设置
5.Bean工厂的设置,例如 设置的类的加载器、El表达式的解析器、添加后置处理器等
6.执行Bean工厂的后置处理器来设置Bean工厂,这个过程会扫描类
7.实例化扫描到的Bean后置处理器
8.国际化资源设置
9.初始化多播器
10.设置定义的监听器到容器中并发布之前的事件
11.实例化非懒加载的单例bean到容器中
12.发布容器刷新完成事件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值