[spring源码]spring启动流程

前言

通常,我们说的Spring启动,就是构造ApplicationContext对象以及调用refresh()方法的过程。

首先,Spring启动过程主要做了这么几件事情:

  1. 构造一个BeanFactory对象
  2. 解析配置类,得到BeanDefinition,并注册到BeanFactory中

    a.解析@ComponentScan,此时就会完成扫描

    b.解析@Import

    c.解析@Bean

    ...

  3. 因为ApplicationContext还支持国际化,所以还需要初始化MessageSource对象
  4. 因为ApplicationContext还支持事件机制,所以还需要初始化ApplicationEventMulticaster对象
  5. 把用户定义的ApplicationListener对象添加到ApplicationContext中,等Spring启动完了就要发布事件了
  6. 创建非懒加载的单例Bean对象,并存在BeanFactory的单例池中。
  7. 调用Lifecycle Bean的start()方法
  8. 发布ContextRefreshedEvent事件

由于Spring启动过程中要创建非懒加载的单例Bean对象,那么就需要用到BeanPostProcessor,所以Spring在启动过程中就需要做两件事:

  1. 生成默认的BeanPostProcessor对象,并添加到BeanFactory中

    a.AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value

    b.CommonAnnotationBeanPostProcessor:处理@Resource、@PostConstruct、@PreDestroy

    c.ApplicationContextAwareProcessor:处理ApplicationContextAware等回调

  2. 找到外部用户所定义的BeanPostProcessor对象(类型为BeanPostProcessor的Bean对象),并添加到BeanFactory中

spring启动流程

AnnotationConfigApplicationContext的构造方法

1.父类构造方法,构造一个DefaultListableBeanFactory

在调用AnnotationConfigApplicationContext的构造方法之前,会调用父类GenericApplicationContext的无参构造方法,会构造一个BeanFactory,为DefaultListableBeanFactory

2.构造AnnotatedBeanDefinitionReader

(主要作用添加一些基础的PostProcessor,同时可以通过reader进行BeanDefinition的注册)同时对BeanFactory进行设置和添加PostProcessor

        a.设置dependencyComparator:AnnotationAwareOrderComparator,它是一个Comparator,是用来进行排序的,会获取某个对象上的Order注解或者通过实现Ordered接口所定义的值进行排序,在日常开发中可以利用这个类来进行排序

        b.设置autowireCandidateResolver:ContextAnnotationAutowireCandidateResolver,用来解析某个Bean能不能进行自动注入,比如某个Bean的autowireCandidate属性是否等于true

        c.向BeanFactory中添加ConfigurationClassPostProcessor对应的BeanDefinition

        d.向BeanFactory中添加AutowiredAnnotationBeanPostProcessor对应的BeanDefinition

        e.向BeanFactory中添加CommonAnnotationBeanPostProcessor对应的BeanDefinition

        f.向BeanFactory中添加EventListenerMethodProcessor对应的BeanDefinition(用来处理@EventListener注解的)

        g.向BeanFactory中添加DefaultEventListenerFactory对应的BeanDefinition(用来处理@EventListener注解的)

3.构造ClassPathBeanDefinitionScanner

主要作用可以用来扫描得到并注册BeanDefinition),同时进行设置:

         a.设置this.includeFilters = AnnotationTypeFilter(Component.class)

        b.设置environment

        c.设置resourceLoader

4.利用reader注册AppConfig为BeanDefinition

refresh()方法

1.prepareRefresh()

refresh()前戏,做容器刷新前的准备工作

        a.记录容器启动时间,设置一些标志位

        b.留给子类的一个模板方法,允许子类设置一些内容到Environment中

        c.验证Environment中是否包括了必须要有的属性

2. obtainFreshBeanFactory()

返回一个DefaultListableBeanFactory,这里会执行refreshBeanFactory()判断容器能否重复刷新

ClassPathXmlApplicationContext继承了AbstractRefreshableConfigApplicationContext是可以刷新的,会执行bean的销毁逻辑,然后重新生成一个BeanFactory

AnnotationConfigApplicationContext继承了GenericApplicationContext,重复刷新会报错

3.prepareBeanFactory(beanFactory)

beanFactory的前戏,beanFactory的准备工作

        a.设置beanFactory的类加载器

        b.设置SpringEL表达式解析器

        c.设置类型转化注册器

        d.添加一个Bean的后置处理器:ApplicationContextAwareProcessor,用于处理回调

        e.添加ignoredDependencyInterface:可以向这个属性中添加一些接口,如果某个类实现了这个接口,并且这个类中的某些set方法在接口中也存在,那么这个set方法在自动注入的时候是不会执行的,比如EnvironmentAware这个接口,如果某个类实现了这个接口,那么就必须实现它的setEnvironment方法,而这是一个set方法,和Spring中的autowire是冲突的,那么Spring在自动注入时是不会调用setEnvironment方法的,而是等到回调Aware接口时再来调用(注意,这个功能仅限于xml的autowire,@Autowired注解是忽略这个属性的)

        f.添加resolvableDependencies:在byType进行依赖注入时,会先从这个属性中根据类型找bean

        g.添加一个Bean的后置处理器:ApplicationListenerDetector,是一个BeanPostProcessor,用来判断某个Bean是不是ApplicationListener,如果是则把这个Bean添加到ApplicationContext中去

        h.添加一个Bean的后置处理器:LoadTimeWeaverAwareProcessor

        i.添加一些单例bean到单例池

                i:"environment":Environment对象

                ii:"systemProperties":系统的一些key-value值

                iii:"systemEnvironment":JVM的一些key-value值

4.postProcessBeanFactory()

留给子类的模板方法,具体的子类,可以继续向BeanFactory中再添加一些东西

5.invokeBeanFactoryPostProcessors(beanFactory)

执行BeanFactoryPostProcessor

第一阶段:

BeanDefinitionRegistryPostProcessor

 程序员添加--->PriorityOrdered(默认ConfigurationClassPostProcessor)--->Ordered--->普通的--->BeanDefinitionRegistryPostProcessor的所有postProcessBeanFactory()方法

        1.执行beanFactoryPostProcessors的postProcessBeanDefinitionRegistry()方法,beanFactoryPostProcessors集合一般情况下都是空的,除非我们手动调用容器的addBeanFactoryPostProcessor方法添加了

        2.执行BeanFactory中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法(此时在BeanFactory中会存在一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor,它也是一个BeanDefinitionRegistryPostProcessor

                i.解析AppConfig类

                ii.扫描得到BeanDefinition并注册

                iii.解析@Import,@Bean等注解得到BeanDefinition并注册

                iv.详细的看另外的笔记,专门分析了ConfigurationClassPostProcessor是如何工作的

                v.在这里,我们只需要知道在这一步会去得到BeanDefinition,而这些BeanDefinition中可能存在BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,所以执行完ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()方法后,还需要继续执行其他BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法

        3.执行BeanFactory中实现了Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法

         4.执行哪些没有实现了PriorityOrdered或Ordered接口的普通BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法,直到没有更多的BeanDefinitionRegistryPostProcessor 出现(在这个过程中可能会向BeanFactory中注册另外的BeanDefinitionRegistryPostProcessor,所以需要while,直到确定所有的BeanDefinitionRegistryPostProcessor都执行完了,在这个过程中注册的BeanDefinitionRegistryPostProcessor,所实现的PriorityOrdered或Ordered接口可能会不按顺序执行)

        5.执行所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法

第二阶段:

BeanFactoryPostProcessor

程序员添加---> PriorityOrdered-->Ordered-->普通的

        1.执行通过ApplicationContext添加进来的BeanFactoryPostProcessor的postProcessBeanFactory()方法

        2.执行BeanFactory中实现了PriorityOrdered接口的BeanFactoryPostProcessor的postProcessBeanFactory()方法

        3.执行BeanFactory中实现了Ordered接口的BeanFactoryPostProcessor的postProcessBeanFactory()方法

        4.执行BeanFactory中普通的BeanFactoryPostProcessor的postProcessBeanFactory()方法

从BeanFactory中找到类型为BeanFactoryPostProcessor的beanName,而这些BeanFactoryPostProcessor包括了上面的BeanDefinitionRegistryPostProcessor

执行还没有执行过的BeanFactoryPostProcessor的postProcessBeanFactory()方法

6.registerBeanPostProcessors(beanFactory)

7. initMessageSource()

初始化国际化资源 ,让ApplicationContext拥有国际化的功能

8.initApplicationEventMulticaster()

初始化广播器,让ApplicationContext拥有事件发布的功能 

 9.onRefresh()

留给子类的模板方法,在特定上下文子类中初始化其他特殊 bean

10.registerListeners()

把实现了ApplicationListener的bean对象注册到ApplicationContext的事件广播器applicationEventMulticaster中去

 11.finishBeanFactoryInitialization(beanFactory)

完成BeanFactory的初始化,主要就是实例化非懒加载的单例Bean

 12.finishRefresh()

完成refresh()

什么是BeanFactoryPostProcessor

BeanPostProcessor表示Bean的后置处理器,是用来对Bean进行加工的,类似的,BeanFactoryPostProcessor理解为BeanFactory的后置处理器,用来用对BeanFactory进行加工的。

Spring支持用户定义BeanFactoryPostProcessor的实现类Bean,来对BeanFactory进行加工,比如:

@Component
public class KunkunBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
		beanDefinition.setAutowireCandidate(false);
	}
}

以上代码,就利用了BeanFactoryPostProcessor来拿到BeanFactory,然后获取BeanFactory内的某个BeanDefinition对象并进行修改,注意这一步是发生在Spring启动时,创建单例Bean之前的,所以此时对BeanDefinition就行修改是会生效的。

所以Spring还提供了一个BeanFactoryPostProcessor的子接口:BeanDefinitionRegistryPostProcessor 

什么是BeanDefinitionRegistryPostProcessor

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

 我们可以看到BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,并新增了一个方法,注意方法的参数为BeanDefinitionRegistry,所以如果我们提供一个类来实现BeanDefinitionRegistryPostProcessor,那么在postProcessBeanDefinitionRegistry()方法中就可以注册BeanDefinition了。比如:

@Component
public class KunkunBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
		beanDefinition.setBeanClass(User.class);
		registry.registerBeanDefinition("user", beanDefinition);
	}

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
		beanDefinition.setAutowireCandidate(false);
	}
}

执行BeanFactoryPostProcessor

  1. 执行通过ApplicationContext添加进来的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  2. 执行BeanFactory中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  3. 执行BeanFactory中实现了Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  4. 执行BeanFactory中普通的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  5. 执行上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法
  6. 执行通过ApplicationContext添加进来的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  7. 执行BeanFactory中实现了PriorityOrdered接口的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  8. 执行BeanFactory中实现了Ordered接口的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  9. 执行BeanFactory中普通的BeanFactoryPostProcessor的postProcessBeanFactory()方法

注册BeanPostProcessors

将扫描到的BeanPostProcessors实例化并排序,并添加到BeanFactory的beanPostProcessors属性中去

1.First, register the BeanPostProcessors that implement PriorityOrdered.

2.Next, register the BeanPostProcessors that implement Ordered.

3.Now, register all regular BeanPostProcessors.

4.Finally, re-register all internal BeanPostProcessors.(MergedBeanDefinitionPostProcessor排在最后,AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor都是其子类)

5.Re-register post-processor for detecting inner beans as ApplicationListeners,moving it to the end of the processor chain (for picking up proxies etc)(ApplicationListenerDetector放在所有BeanPostProcessor之后)

Lifecycle的使用

Lifecycle表示的是ApplicationContext的生命周期,可以定义一个SmartLifecycle来监听ApplicationContext的启动和关闭:

@Component
public class KunkunLifecycle implements SmartLifecycle {

	private boolean isRunning = false;

	@Override
	public void start() {
		System.out.println("启动");
		isRunning = true;
	}

	@Override
	public void stop() {
        // 要触发stop(),要调用context.close(),或者注册关闭钩子(context.registerShutdownHook();)
		System.out.println("停止");
		isRunning = false;
	}

	@Override
	public boolean isRunning() {
		return isRunning;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值