当前位置:   article > 正文

【SpringIOC源码解析】一——IOC容器启动流程_spring ioc启动流程

spring ioc启动流程

什么是IOC

IoC只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是在类内部主动创建依赖对象,从而导致类与类之间高耦合;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

Spring Framework对控制反转(IoC)原理的实现。IoC也称为依赖注入(DI)。这是一个过程,通过这个过程,对象只能通过构造函数参数,工厂方法的参数或在构造或从工厂方法返回后在对象实例上设置的属性来定义它们的依赖关系(即,它们使用的其他对象)。 然后容器在创建bean时注入这些依赖项。此过程基本上是bean本身的逆(因此名称,控制反转),通过使用类的直接构造或诸如服务定位器模式的机制来控制其依赖关系的实例化或位置。(官方文档5.x说明)

在spring中,对象和对象依赖关系怎么表示?

  • 可以用 xml , properties 文件等语义化配置文件表示。
  • 可以基于注解配置,Spring 2.5引入了对基于注释的配置元数据的支持@Service,@Component,@Contorller。
  • 可以基于java配置,从Spring 3.0开始,Spring JavaConfig项目提供的许多功能成为核心Spring Framework的一部分。因此,您可以使用Java而不是XML文件在应用程序类外部定义bean。要使用这些新功能,请参阅 @Configuration, @Bean, @Import,和@Depend

Spirng Bean 生命周期

  1. 初始化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为连Autowired注解都是没有解析的;
  2. 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了;
  3. 如果Bean实现了BeanNameAware接口,则调用setBeanName方法;
  4. 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;
  5. 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;
  6. 调用BeanPostProcessor的postProcessBeforeInitialization方法;
  7. 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法;
  8. 如果Bean定义了init-method方法,则调用Bean的init-method方法;
  9. 调用BeanPostProcessor的postProcessAfterInitialization方法;当进行到这一步,Bean已经被准备就绪了,一直停留在应用的上下文中,直到被销毁;
  10. 如果应用的上下文被销毁了,如果Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method声明了销毁方法也会被调用。

Spring IOC体系结构

 1.BeanFactory

         Spring Bean的创建是典型的工厂模式,这一系列的Bean工厂,也即IOC容器为开发者管理对象间的依赖关系提供了很多便利和基础服务,在Spring中有许多的IOC容器的实现供用户选择和使用,其相互关系如下:

 

其中BeanFactory作为最顶层的一个接口类,它定义了IOC容器的基本功能规范,即定义获取bean和bean的各种属性。BeanFactory 有三个子类:ListableBeanFactory、HierarchicalBeanFactory 和AutowireCapableBeanFactory。但是从上图中我们可以发现最终的默认实现类是 DefaultListableBeanFactory,他实现了所有的接口。那为何要定义这么多层次的接口呢?查阅这些接口的源码和说明发现,每个接口都有他使用的场合,它主要是为了区分 Spring 内部在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制。例如 ListableBeanFactory 接口表示这些 Bean 是可列表的,而 HierarchicalBeanFactory 表示的是在应用中可以起多个 BeanFactory,然后可以将各个 BeanFactory 设置为父子关系。AutowireCapableBeanFactory 接口定义 Bean 的自动装配规则。这四个接口共同定义了 Bean 的集合、Bean 之间的关系、以及 Bean 行为。

2.ApplicationContext

在BeanFactory里只对IOC容器的基本行为作了定义,根本不关心你的bean是如何定义怎样加载的。正如我们只关心工厂里得到什么的产品对象,至于工厂是怎么生产这些对象的,这个基本的接口不关心。

而要知道工厂是如何产生对象的,我们需要看具体的IOC容器实现,spring提供了许多IOC容器的实现。比如XmlBeanFactory,ClasspathXmlApplicationContext等。其中XmlBeanFactory就是针对最基本的ioc容器的实现,这个IOC容器可以读取XML文件定义的BeanDefinition(XML文件中对bean的描述),如果说XmlBeanFactory是容器中的屌丝,ApplicationContext应该算容器中的高帅富.

IoC容器的初始化包括BeanDefinition的Resource定位、载入和注册这三个基本的过程。ApplicationContext是Spring提供的一个高级的IoC容器, 它除了能够提供IoC容器的基本功能外,还为用户提供了以下的附加服务:

1.  支持信息源,可以实现国际化(实现MessageSource接口)

2.  访问资源(实现ResourcePatternResolver接口)

3.  支持应用事件(实现ApplicationEventPublisher接口)

3.BeanDefinition

SpringIOC容器管理了我们定义的各种Bean对象及其相互的关系,Bean对象在Spring实现中是以BeanDefinition来描述的,其继承体系如下:

Bean 的解析过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证有足够的灵活性,以应对可能的变化。Bean 的解析主要就是对 Spring 配置文件的解析。这个解析过程主要通过下图中的类完成:


容器ApplicationContext启动流程

后文将以xml文件加载的方式阐述容器的整个启动过程,先看下最启动 Spring 容器的代码:

  1. public static void main(String[] args) {
  2. ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
  3. }

第一步,我们肯定要从 ClassPathXmlApplicationContext 的构造方法说起。

  1. public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {
  2. super(parent);
  3. //根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割)
  4. setConfigLocations(configLocations);
  5. if (refresh) {
  6. //核心方法
  7. refresh();
  8. }
  9. }

ClsassPathXmlApplicationContext支持多个配置文件以数组方式同时传入

  1. public void setConfigLocations(@Nullable String... locations) {
  2. if (locations != null) {
  3. Assert.noNullElements(locations, "Config locations must not be null");
  4. this.configLocations = new String[locations.length];
  5. for (int i = 0; i < locations.length; i++) {
  6. this.configLocations[i] = resolvePath(locations[i]).trim();
  7. }
  8. }
  9. else {
  10. this.configLocations = null;
  11. }
  12. }

设置了路径之后,便可以根据路径做配置文件的解析以及各种功能的实现了,可以说Refresh()中包含了几乎 ApplicationContext中提供的全部功能,而且此函数中逻辑非常清晰明了。

  1. //AbstractApplicationContext 515行
  2. public void refresh() throws BeansException, IllegalStateException {
  3. //ApplicationContext 建立起来以后,是可以通过调用 refresh() 这个方法重建的,需要锁保证操作原子性
  4. synchronized (this.startupShutdownMonitor) {
  5. //准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
  6. prepareRefresh();
  7. // 这步比较关键,这步完成后,xml配置文件就会解析成BeanDefinition定义,注册到 BeanFactory中,
  8. // 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
  9. // 注册也只是将这些信息都保存到了注册中心(核心是一个 beanName-> beanDefinition 的 map)
  10. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  11. //对BeanFactory进行各种功能填充,如设置BeanFactory的类加载器,添加 BeanPostProcessor,注册特殊的BeanAware
  12. prepareBeanFactory(beanFactory);
  13. try {
  14. //这里是提供给子类覆盖做扩展处理,比如具体的子类可以在这步的时候添加BeanFactoryPostProcessor的实现类或做点什么事
  15. postProcessBeanFactory(beanFactory);
  16. //调用BeanFactoryPostProcessor各个实现类的postProcessBeanFactory() 方法
  17. invokeBeanFactoryPostProcessors(beanFactory);
  18. //注册BeanPostProcessor的实现类,注意看和BeanFactoryPostProcessor的区别
  19. //这里只是注册,真正的调用是在getBean(),即真正实例化的时候
  20. registerBeanPostProcessors(beanFactory);
  21. //为上下文初始化Message源,即不同语言的消息体, 国际化处理
  22. initMessageSource();
  23. //初始化当前 ApplicationContext 的事件广播器
  24. initApplicationEventMulticaster();
  25. //典型的模板方法(钩子方法),
  26. //留给子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
  27. onRefresh();
  28. //在所有注册的bean中查找Listenerbean注册到消息广播报器中
  29. registerListeners();
  30. // 重点
  31. // 初始化所有的singletonBeans(lazy-init的除外)
  32. finishBeanFactoryInitialization(beanFactory);
  33. //最后,广播事件,ApplicationContext 初始化完成
  34. finishRefresh();
  35. }
  36. catch (BeansException ex) {
  37. if (logger.isWarnEnabled()) {
  38. logger.warn("Exception encountered during context initialization - " +
  39. "cancelling refresh attempt: " + ex);
  40. }
  41. // Destroy already created singletons to avoid dangling resources.
  42. destroyBeans();
  43. // Reset 'active' flag.
  44. cancelRefresh(ex);
  45. // Propagate exception to caller.
  46. throw ex;
  47. }
  48. finally {
  49. // Reset common introspection caches in Spring's core, since we
  50. // might not ever need metadata for singleton beans anymore...
  51. resetCommonCaches();
  52. }
  53. }
  54. }

下面概括一下refresh()初始化的步骤,并从中解释一下它为我们供的功能

1. 初始化前的准备工作,例如对系统属性或者环境变量进行准备及验证。在某种情况下项目的使用需要读取某些系统变量,而这个变量的设置很可能会影响着系统的正确性,那么 classPathXmlApplicationContext 为我们提供的这个准备函数就显得非常必要,它可以在 Spring 启动的时候提前对必须的变量进行存在性验证。

2. 初始化BeanFactory并进行 XML文件读取

之前有提到classPathXmlApplicationContext 包含 BeanFacto ry 所提供的一切特征,那么在这一步骤中将会复用 BeanFactory 中的配置文件读取解析及其他功能,这一步之后,ClassPathXmlApplicationContext 实际上就已包含了beanFactory 所提供的功能,也就是可以进行 bean 的提取等基础操作了。

3. BeanFactory 进行各种功能填充

@Qualifier @Autowired 应该是大家非常熟悉的注解 ,那么这两个注解正是在这个步骤中增加的支持

4. 子类覆盖postProcessBeanFactory(beanFactory)方法做额外的处理

Spring 之所以强大,为世人所推崇,除了它功能上为大家提供了便利外,还有一方面是它的完美架构,开放式的架构让使用它的程序员很容易根据业务需要扩展已经存在的功能,这种开放式的设计在Spring中随处可见,例如在本例中就提供了一个空的函数实现 postProcessBeanFactory 来方便程序员在业务上做进一步扩展。

5. 激活各种 BeanFactory 处理器

6. 注册拦截 bean 创建的 bean 处理器,这里只是注册,真正的调用是在 getBean 时候

7. 为上下文初始化 Message 源,即对不同语言的消息体进行国际化处理

8. 初始化应用消息广播器,并放入“app licatio EventMulticaster”bean中

9. 给子类来初始化其他的 bean

10. 在所有注册的 bean中查找listener bean 注册到消息广播器中

11. 初始化单实例(非惰性的)

12. 完成刷新过程,通知生命周期处理器 lifecycleProcessor 刷新过程,同时发出 ContextRefreshEvent 通知

下面,我们开始一步步来肢解这个 refresh() 方法

1.环境准备

prepareRefresh 函数主要是做些准备工作,例如对系统属性及环境变量的初始化及验证

  1. protected void prepareRefresh() {
  2. //记录时间与状态
  3. this.startupDate = System.currentTimeMillis();
  4. this.closed.set(false);
  5. this.active.set(true);
  6. if (logger.isDebugEnabled()) {
  7. if (logger.isTraceEnabled()) {
  8. logger.trace("Refreshing " + this);
  9. }
  10. else {
  11. logger.debug("Refreshing " + getDisplayName());
  12. }
  13. }
  14. // 子类覆盖
  15. initPropertySources();
  16. //验证需要的配置文件是否已经放到环境中
  17. getEnvironment().validateRequiredProperties();
  18. // Store pre-refresh ApplicationListeners...
  19. if (this.earlyApplicationListeners == null) {
  20. this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
  21. }
  22. else {
  23. // Reset local application listeners to pre-refresh state.
  24. this.applicationListeners.clear();
  25. this.applicationListeners.addAll(this.earlyApplicationListeners);
  26. }
  27. // Allow for the collection of early ApplicationEvents,
  28. // to be published once the multicaster is available...
  29. this.earlyApplicationEvents = new LinkedHashSet<>();
  30. }

这个函数的最大的可用之处还是开放式设计,举个例子,软件在运行中有一个重要的设置项(如HOME)需要在系统环境变量中读取,,如果用户没有在系统环境变量中配置这个参数,那么工程应该不能工作。这一要求在spring中可以这么实现:

自定义容器启动类继承ClassPathXmlApplicationContext

  1. public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {
  2. public MyClassPathXmlApplicationContext(String ...configLocations) {
  3. super(configLocations);
  4. }
  5. @Override
  6. protected void initPropertySources() {
  7. //添加验证要求
  8. getEnvironment().setRequiredProperties("HOME");
  9. }
  10. }
  1. public static void main(String[] args) {
  2. MyClassPathXmlApplicationContext applicationContext = new MyClassPathXmlApplicationContext("application.xml");
  3. }

2.创建BeanFactory容器,加载注册BeanDefinitiion

ApplicationContext是对BeanFactory的功能上的扩展,那么obtainFreshBeanFactory正是实现 BeanFactory的地方,这个方法是全文最重要的部分之一,这里将会初始化 BeanFactory、加载 Bean配置、注册 BeanDefinition 等等。以后所有的 BeanFactory 相关的操作其实是委托给这个实例来处理的。

  1. //AbstractApplicationContext 635行
  2. protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
  3. refreshBeanFactory();
  4. return getBeanFactory();
  5. }
  1. //AbstractRefreshableApplicationContext 124行
  2. protected final void refreshBeanFactory() throws BeansException {
  3. //销毁当前ApplicationContext已有的BeanFactory
  4. if (hasBeanFactory()) {
  5. destroyBeans();
  6. closeBeanFactory();
  7. }
  8. try {
  9. // 初始化一个 DefaultListableBeanFactory
  10. DefaultListableBeanFactory beanFactory = createBeanFactory();
  11. // 用于BeanFactory的序列化
  12. beanFactory.setSerializationId(getId());
  13. // 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
  14. customizeBeanFactory(beanFactory);
  15. // xml文件读取解析,加载 Bean 到 BeanFactory 中
  16. loadBeanDefinitions(beanFactory);
  17. synchronized (this.beanFactoryMonitor) {
  18. this.beanFactory = beanFactory;
  19. }
  20. }
  21. catch (IOException ex) {
  22. throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
  23. }
  24. }

定制BeanFactory

  1. //AbstractRefreshableApplicationContext 224行
  2. protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
  3. // 是否允许 Bean 定义覆盖
  4. if (this.allowBeanDefinitionOverriding != null) {
  5. beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
  6. }
  7. // 是否允许 Bean 间的循环依赖
  8. if (this.allowCircularReferences != null) {
  9. beanFactory.setAllowCircularReferences(this.allowCircularReferences);
  10. }
  11. }

BeanDefinition 的覆盖问题可能会有开发者碰到这个坑,就是在配置文件中定义 bean 时使用了相同的 id 或 name,默认情况下,allowBeanDefinitionOverriding 属性为 null,如果在同一配置文件中重复了,会抛错,但是如果不是同一配置文件中,会发生覆盖。

循环引用也很好理解:A 依赖 B,而 B 依赖 A。或 A 依赖 B,B 依赖 C,而 C 依赖 A。

默认情况下,Spring 允许单例属性的循环依赖,当然如果你在 A 的构造方法中依赖 B,在 B 的构造方法中依赖 A 是不行的。

loadBeanDefinitions

接下来是最重要的 loadBeanDefinitions(beanFactory) 方法了,这个方法将根据配置,加载各个 Bean,然后放到 BeanFactory 中。

读取配置的操作在 XmlBeanDefinitionReader 中,其负责加载配置、解析。

  1. //AbstractXmlApplicationContext 81行
  2. protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
  3. // Create a new XmlBeanDefinitionReader for the given BeanFactory.
  4. XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
  5. //进行环境变量配置
  6. beanDefinitionReader.setEnvironment(this.getEnvironment());
  7. beanDefinitionReader.setResourceLoader(this);
  8. beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
  9. //子类覆盖扩展,进行定制化配置
  10. initBeanDefinitionReader(beanDefinitionReader);
  11. loadBeanDefinitions(beanDefinitionReader);
  12. }
  1. //AbstractXmlApplicationContext 121行
  2. protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
  3. Resource[] configResources = getConfigResources();
  4. if (configResources != null) {
  5. reader.loadBeanDefinitions(configResources);
  6. }
  7. String[] configLocations = getConfigLocations();
  8. if (configLocations != null) {
  9. reader.loadBeanDefinitions(configLocations);
  10. }
  11. }

后续就是XmlBeanDefinitionReader对xml 文件的解析,并将加载后的BeanDefinition注册到DefaultListableBeanFactory中,具体过程请看Spring IOC源码解析篇二。

3.功能扩展prepareBeanFactory

进入函数 prepareBeanFactory前,Spring已经完成了对配置的解析,ApplicationContext 在功能上的扩展也由此展开。

  1. //AbstractApplicationContext 645行
  2. protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  3. //设置beanFactory的classLoader为当前context的classLoader
  4. beanFactory.setBeanClassLoader(getClassLoader());
  5. //设置beanFactory的表达式语言处理器,Spring3增加了表达式语言的支持,默认可以使用#{bean.xxx}的形式来调用相关属性值
  6. beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  7. //为 beanFactory增加了一个默认propertyEditor,这个主要是对 bean 的属性等设置管理的一个个工具
  8. beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
  9. // Configure the bean factory with context callbacks.
  10. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
  11. //设置了几个忽略自动装配的接口,如果某个 bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们
  12. beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
  13. beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
  14. beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
  15. beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
  16. beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
  17. beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
  18. //设置了几个自动装配的特殊规则,如果有 bean 依赖了以下几个,会注入这边相应的值
  19. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
  20. beanFactory.registerResolvableDependency(ResourceLoader.class, this);
  21. beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
  22. beanFactory.registerResolvableDependency(ApplicationContext.class, this);
  23. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
  24. //增加对AspectJ的支持
  25. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
  26. beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
  27. // Set a temporary ClassLoader for type matching.
  28. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  29. }
  30. //添加默认的系统环境bean
  31. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
  32. beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
  33. }
  34. if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
  35. beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
  36. }
  37. if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
  38. beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
  39. }
  40. }

上面函数主要进行了几个方面的扩展

  • 增加对SpEL言的支持

  • 增加对属性编辑器的支持

  • 增加对一些内置类,比如EnvironmentAware、MessageSourceAware的信息注入

  • 设置了依赖功能可忽略的接口

  • 注册一些固定依赖的属性

  • 增加 AspectJ的支持

  • 将相关环境变量及属性注册以单例模式注册

4.调用BeanFactory后处理

  1. //PostProcessorRegistrationDelegate 55行
  2. public static void invokeBeanFactoryPostProcessors(
  3. ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  4. // Invoke BeanDefinitionRegistryPostProcessors first, if any.
  5. Set<String> processedBeans = new HashSet<>();
  6. //对 BeanDefinitionRegistry容器类型的处理
  7. if (beanFactory instanceof BeanDefinitionRegistry) {
  8. BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
  9. List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
  10. List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
  11. //硬编码注册的后处理器
  12. for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
  13. if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
  14. BeanDefinitionRegistryPostProcessor registryProcessor =
  15. (BeanDefinitionRegistryPostProcessor) postProcessor;
  16. //对于BeanDefinitionRegistryPostProcessor类型,在BeanFactoryPostProcessor的基础上还有自己定义的方法,需要先调用
  17. registryProcessor.postProcessBeanDefinitionRegistry(registry);
  18. registryProcessors.add(registryProcessor);
  19. }
  20. else {
  21. regularPostProcessors.add(postProcessor);
  22. }
  23. }
  24. //配置注册的BeanDefinitionRegistryPostProcessor后处理器
  25. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
  26. //执行实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的registry后置处理方法
  27. String[] postProcessorNames =
  28. beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  29. for (String ppName : postProcessorNames) {
  30. if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  31. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  32. processedBeans.add(ppName);
  33. }
  34. }
  35. //对后处理器排序
  36. sortPostProcessors(currentRegistryProcessors, beanFactory);
  37. //用于后面执行postProcessBeanFactory()
  38. registryProcessors.addAll(currentRegistryProcessors);
  39. //postProcessBeanFactory()前先执行自己的postProcessBeanDefinitionRegistry() invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  40. currentRegistryProcessors.clear();
  41. //执行实现Ordered接口的BeanDefinitionRegistryPostProcessor
  42. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  43. for (String ppName : postProcessorNames) {
  44. if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
  45. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  46. processedBeans.add(ppName);
  47. }
  48. }
  49. sortPostProcessors(currentRegistryProcessors, beanFactory);
  50. registryProcessors.addAll(currentRegistryProcessors);
  51. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  52. currentRegistryProcessors.clear();
  53. //执行其他BeanDefinitionRegistryPostProcessors
  54. boolean reiterate = true;
  55. while (reiterate) {
  56. reiterate = false;
  57. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  58. for (String ppName : postProcessorNames) {
  59. if (!processedBeans.contains(ppName)) {
  60. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  61. processedBeans.add(ppName);
  62. reiterate = true;
  63. }
  64. }
  65. sortPostProcessors(currentRegistryProcessors, beanFactory);
  66. registryProcessors.addAll(currentRegistryProcessors);
  67. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  68. currentRegistryProcessors.clear();
  69. }
  70. // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
  71. //这里才执行postProcessBeanFactory()
  72. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
  73. invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
  74. }
  75. else {
  76. // Invoke factory processors registered with the context instance.
  77. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
  78. }
  79. //处理配置注册的BeanFactoryPostProcessor
  80. String[] postProcessorNames =
  81. beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
  82. // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
  83. // Ordered, and the rest.
  84. //对后处理进行分类
  85. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
  86. List<String> orderedPostProcessorNames = new ArrayList<>();
  87. List<String> nonOrderedPostProcessorNames = new ArrayList<>();
  88. for (String ppName : postProcessorNames) {
  89. if (processedBeans.contains(ppName)) {
  90. // skip - already processed in first phase above
  91. }
  92. else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  93. priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
  94. }
  95. else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
  96. orderedPostProcessorNames.add(ppName);
  97. }
  98. else {
  99. nonOrderedPostProcessorNames.add(ppName);
  100. }
  101. }
  102. //按照优先级排序
  103. sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
  104. invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
  105. //按照Ordered排序
  106. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
  107. for (String postProcessorName : orderedPostProcessorNames) {
  108. orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  109. }
  110. sortPostProcessors(orderedPostProcessors, beanFactory);
  111. invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
  112. //无序,直接调用
  113. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
  114. for (String postProcessorName : nonOrderedPostProcessorNames) {
  115. nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  116. }
  117. invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
  118. // Clear cached merged bean definitions since the post-processors might have
  119. // modified the original metadata, e.g. replacing placeholders in values...
  120. beanFactory.clearMetadataCache();
  121. }

从上面的方法中我们看到,对于BeanFactoryPostProcessor的处理主要分两种情况进行,一个是对于BeanDefinitionRegistry类的特殊处理,另一种是对普通的 BeanFactoryPostProcessor 进行处理,而对于每种情况都需要考虑硬编码注入注册的后处理器以及通过配置注入的后处理器。

5.注册BeanPostProcessor

现在我们来探索BeanPostProcessor,这里并不是调用,而是注注册,真正调用其实是在 bean的实例化阶段。

  1. //PostProcessorRegistrationDelegate 188行
  2. public static void registerBeanPostProcessors(
  3. ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
  4. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
  5. // Register BeanPostProcessorChecker that logs an info message when
  6. // a bean is created during BeanPostProcessor instantiation, i.e. when
  7. // a bean is not eligible for getting processed by all BeanPostProcessors.
  8. int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
  9. beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
  10. // Separate between BeanPostProcessors that implement PriorityOrdered,
  11. // Ordered, and the rest.
  12. //使用PriorityOrdered保证顺序
  13. List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
  14. List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
  15. //使 Ordered 保证顺序
  16. List<String> orderedPostProcessorNames = new ArrayList<>();
  17. //无序 BeanPostProcessor
  18. List<String> nonOrderedPostProcessorNames = new ArrayList<>();
  19. for (String ppName : postProcessorNames) {
  20. if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  21. BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
  22. priorityOrderedPostProcessors.add(pp);
  23. if (pp instanceof MergedBeanDefinitionPostProcessor) {
  24. internalPostProcessors.add(pp);
  25. }
  26. }
  27. else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
  28. orderedPostProcessorNames.add(ppName);
  29. }
  30. else {
  31. nonOrderedPostProcessorNames.add(ppName);
  32. }
  33. }
  34. //第1步,注册所有实现PriorityOrdered的BeanPostProcessor
  35. sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
  36. registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
  37. //第2步, 注册所有实现Ordered的BeanPostProcessor
  38. List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
  39. for (String ppName : orderedPostProcessorNames) {
  40. BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
  41. orderedPostProcessors.add(pp);
  42. if (pp instanceof MergedBeanDefinitionPostProcessor) {
  43. internalPostProcessors.add(pp);
  44. }
  45. }
  46. sortPostProcessors(orderedPostProcessors, beanFactory);
  47. registerBeanPostProcessors(beanFactory, orderedPostProcessors);
  48. //第3步, 注册所有无序的BeanPostProcessor
  49. List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
  50. for (String ppName : nonOrderedPostProcessorNames) {
  51. BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
  52. nonOrderedPostProcessors.add(pp);
  53. if (pp instanceof MergedBeanDefinitionPostProcessor) {
  54. internalPostProcessors.add(pp);
  55. }
  56. }
  57. registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
  58. //第4步,注册 MergedBeanDefitionPostProcessor类型的BeanPostProcessor
  59. sortPostProcessors(internalPostProcessors, beanFactory);
  60. registerBeanPostProcessors(beanFactory, internalPostProcessors);
  61. //添加ApplicationListener探测器
  62. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
  63. }

6.初始化实事件传播器

initapplicationEventMulticaster方式比较简,无非考虑两种情况。

  • 如果用户自义了事件广播器,那么使用用户自定义的事件广播器
  • 如果用户没有自定义事件广播器,那么使用默认的ApplicationEventMulticaster
  1. //AbstractApplicationContext 762行
  2. protected void initApplicationEventMulticaster() {
  3. ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  4. if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
  5. this.applicationEventMulticaster =
  6. beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
  7. if (logger.isTraceEnabled()) {
  8. logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
  9. }
  10. }
  11. else {
  12. this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
  13. beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
  14. if (logger.isTraceEnabled()) {
  15. logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
  16. "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
  17. }
  18. }
  19. }

作为广播器,一定是用于存放监昕器并在合适的时候调用监听器,那么我们不妨进入默认的广播器实现SimpleAppli cationEventMulticaster探究

  1. public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
  2. ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
  3. //遍历监听器,调用回调
  4. for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
  5. Executor executor = getTaskExecutor();
  6. if (executor != null) {
  7. executor.execute(() -> invokeListener(listener, event));
  8. }
  9. else {
  10. invokeListener(listener, event);
  11. }
  12. }
  13. }
  14. protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
  15. //包一层异常处理机制
  16. ErrorHandler errorHandler = getErrorHandler();
  17. if (errorHandler != null) {
  18. try {
  19. doInvokeListener(listener, event);
  20. }
  21. catch (Throwable err) {
  22. errorHandler.handleError(err);
  23. }
  24. }
  25. else {
  26. doInvokeListener(listener, event);
  27. }
  28. }
  29. private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
  30. try {
  31. //调用监听方法
  32. listener.onApplicationEvent(event);
  33. }
  34. catch (ClassCastException ex) {
  35. String msg = ex.getMessage();
  36. if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
  37. // Possibly a lambda-defined listener which we could not resolve the generic event type for
  38. // -> let's suppress the exception and just log a debug message.
  39. Log logger = LogFactory.getLog(getClass());
  40. if (logger.isDebugEnabled()) {
  41. logger.debug("Non-matching event type for listener: " + listener, ex);
  42. }
  43. }
  44. else {
  45. throw ex;
  46. }
  47. }
  48. }

7.注册监听器

  1. protected void registerListeners() {
  2. //注册硬编码的监听器
  3. for (ApplicationListener<?> listener : getApplicationListeners()) {
  4. getApplicationEventMulticaster().addApplicationListener(listener);
  5. }
  6. //注册配置文件的监听器
  7. String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
  8. for (String listenerBeanName : listenerBeanNames) {
  9. getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
  10. }
  11. //发布注册监听器之前已经发生的事件
  12. Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
  13. this.earlyApplicationEvents = null;
  14. if (earlyEventsToProcess != null) {
  15. for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
  16. getApplicationEventMulticaster().multicastEvent(earlyEvent);
  17. }
  18. }
  19. }

8.初始化非延迟加载单例

完成BeanFactory的初始化工作,其中包括ConversionService的设置、 配置冻结,以及非延迟加载的bean初始化工作。

  1. //AbstractApplicationContext 849行
  2. protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
  3. //初始化conversion服务,加载实现Converter接口的自定义类型转换器
  4. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
  5. beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
  6. beanFactory.setConversionService(
  7. beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
  8. }
  9. // Register a default embedded value resolver if no bean post-processor
  10. // (such as a PropertyPlaceholderConfigurer bean) registered any before:
  11. // at this point, primarily for resolution in annotation attribute values.
  12. if (!beanFactory.hasEmbeddedValueResolver()) {
  13. beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
  14. }
  15. // 先初始化 LoadTimeWeaverAware 类型的 Bean之前也说过,这是 AspectJ
  16. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
  17. for (String weaverAwareName : weaverAwareNames) {
  18. getBean(weaverAwareName);
  19. }
  20. // Stop using the temporary ClassLoader for type matching.
  21. beanFactory.setTempClassLoader(null);
  22. //冻结所有的 bean定义,spring开始预初始化,说明注册的 bean 定义将不被修改或进行任何进一步的处理
  23. beanFactory.freezeConfiguration();
  24. //开始初始化所有单例bean
  25. beanFactory.preInstantiateSingletons();
  26. }
  1. //DefaultListableBeanFactory 816行
  2. public void preInstantiateSingletons() throws BeansException {
  3. if (logger.isTraceEnabled()) {
  4. logger.trace("Pre-instantiating singletons in " + this);
  5. }
  6. // Iterate over a copy to allow for init methods which in turn register new bean definitions.
  7. // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
  8. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
  9. // Trigger initialization of all non-lazy singleton beans...
  10. for (String beanName : beanNames) {
  11. //合并父 Bean 中的配置
  12. RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
  13. // 加载非抽象、非懒加载的 singletons。如果配置了 'abstract = true',那是不需要初始化的
  14. if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
  15. if (isFactoryBean(beanName)) {
  16. //FactoryBean的话,在beanName前面加上‘&’ 符号,再调用 getBean
  17. Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
  18. if (bean instanceof FactoryBean) {
  19. final FactoryBean<?> factory = (FactoryBean<?>) bean;
  20. //判断当前FactoryBean是否是 martFactoryBean的实现
  21. boolean isEagerInit;
  22. if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
  23. isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
  24. ((SmartFactoryBean<?>) factory)::isEagerInit,
  25. getAccessControlContext());
  26. }
  27. else {
  28. isEagerInit = (factory instanceof SmartFactoryBean &&
  29. ((SmartFactoryBean<?>) factory).isEagerInit());
  30. }
  31. if (isEagerInit) {
  32. getBean(beanName);
  33. }
  34. }
  35. }
  36. else {
  37. //对于普通的Bean,只要调用getBean(beanName)这个方法就可以进行初始化了
  38. getBean(beanName);
  39. }
  40. }
  41. }
  42. // 到这里说明所有的非懒加载的 singleton beans 已经完成了初始化
  43. // 如果我们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里得到回调
  44. for (String beanName : beanNames) {
  45. Object singletonInstance = getSingleton(beanName);
  46. if (singletonInstance instanceof SmartInitializingSingleton) {
  47. final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
  48. if (System.getSecurityManager() != null) {
  49. AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
  50. smartSingleton.afterSingletonsInstantiated();
  51. return null;
  52. }, getAccessControlContext());
  53. }
  54. else {
  55. smartSingleton.afterSingletonsInstantiated();
  56. }
  57. }
  58. }
  59. }

bean的完整初始化过程在getBean()方法中实现,请移步到SpringIOC源码解析篇三详细浏览。

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/241504
推荐阅读
相关标签
  

闽ICP备14008679号