Spring注解开发,Spring容器创建概述

Java 投稿 51300 0 评论

Spring注解开发,Spring容器创建概述

浅尝Spring注解开发_Spring容器创建概述,概述Spring容器创建的过程,包括12个方法的执行。

概述12个方法

	//获取ioc容器
	AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfPropertyValues.class);
	/**
	 * 创建一个新的AnnotationConfigApplicationContext,派生bean定义
	 * 从给定的带注释的类,并自动刷新上下文。
	 * @param 类一个或多个带注释的类
	 * e.g. {@link Configuration @Configuration} classes
	 */
	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		this();
		register(annotatedClasses);
		refresh();
	}
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 为刷新准备此上下文。
			prepareRefresh();

			// 告诉子类刷新内部bean工厂。
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 准备在此上下文中使用bean工厂。
			prepareBeanFactory(beanFactory);

			try {
				// 允许在上下文子类中对bean工厂进行后处理。
				postProcessBeanFactory(beanFactory);

				// 调用在上下文中注册为bean的工厂处理器。
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册拦截bean创建的bean处理器。
				registerBeanPostProcessors(beanFactory);

				// 初始化此上下文的消息源。
				initMessageSource();

				// 为此上下文初始化事件多播。
				initApplicationEventMulticaster();

				// 在特定的上下文子类中初始化其他特殊bean。
				onRefresh();

				// 检查监听器bean并注册它们。
				registerListeners();

				// 实例化所有剩余的(非lazy-init)单例。
				finishBeanFactoryInitialization(beanFactory);

				// 最后一步:发布相应的事件。
				finishRefresh();
			}
        	//...

BeanFactory预处理

BeanFactory的创建及预准备工作

  • BeanFactory 的作用是负责 bean 的创建、依赖注入和初始化,bean 的各项特征由 BeanDefinition 定义

  • BeanDefinition 作为 bean 的设计蓝图,规定了 bean 的特征,如单例多例、依赖关系、初始销毁方法等

  • BeanDefinition 的来源有多种多样,可以是通过 xml 获得、配置类获得、组件扫描获得,也可以是编程添加

  • 所有的 BeanDefinition 会存入 BeanFactory 中的 beanDefinitionMap 集合

1、

  1. 先调用父类构造器

  2. 声明两个类,通过读取注解或者扫描类路径读取

  3. 初始化了DefaultListableBeanFactory:基于bean定义元数据的成熟bean工厂,可通过后处理器进行扩展,内部定义了 的属性名,可以操作

  4. 注册了多个(6个)默认的后置处理器

2、

  1. 校验传入的 配置类的注解(是否需要忽略)

  2. 处理通用注解

  3. 封装为后,注册到容器中

  4. 相当于将JavaConfig配置类作为一个Bean注册到容器中

3、Spring容器的:创建刷新

  1. :刷新前的预处理

    1. :初始化一些属性设置,空方法,留给子类自定义个性化的属性设置方法

    2. :检验属性的合法等

    3. :保存容器中的一些早期的事件,一旦多播机可用就会发布

  2. :获取新鲜的

    1. 创建了一个。补充:这个方法在创建的父类的无参构造时调用了,注释是

    2. 设置id

    3. 类注释:

    4. :刷新[创建]

    5. :返回刚才创建的对象

    6. 将创建的[类型:]返回

  3. :的预准备工作(进行一些设置)

    1. : 上下文环境

    2. :系统属性

    3. :系统环境变量

    4. 设置的类加载器、支持表达式解析器...

    5. 添加部分[类型:]

    6. 设置忽略的自动装配的接口、、

    7. 注册可以解析的自动装配;我们能直接在任何组件中自动注入:、、、

    8. 添加[类型:],将用于检测内部 bean 的早期后处理器注册为

    9. 添加编译时的

    10. 给中注册一些能用的组件;

  4. :准备工作完成后进行的后置处理工作

    1. 子类通过重写这个方法来在创建并预准备完成以后做进一步的设置

执行BeanFactoryPostProcessor

BeanFactoryPostProcessor是beanFactory的后置处理器

  • BeanFactoryPostProcessor是beanFactory的后置处理器,在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容,所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建

  • 执行BeanFactoryPostProcessor分两步,先执行BeanDefinitionRegistryPostProcessor,后执行BeanFactoryPostProcessor

  1. :执行的方法。:的后置处理器。在标准初始化(以上4步)之后执行的,两个接口:、

    • 先执行

    • 再执行的方法

    1. 获取所有的

    2. 看先执行实现了优先级接口的

    3. 再执行实现了顺序接口的

    4. 最后执行没有实现任何优先级或者是顺序接口的

    5. 获取所有的

    6. 看先执行实现了优先级接口的

    7. 再执行实现了顺序接口的

    8. 最后执行没有实现任何优先级或者是顺序接口的

    9. 执行的方法

注册BeanPostProcessor

按照优先级注册后置处理器,不执行

  1. :注册(Bean的后置处理器)拦截Bean的创建

    不同接口类型的,在Bean创建前后的执行时机是不一样的

    • 后置处理器

    • 销毁感知后置处理器

    • 实例化感知后置处理器

    • 智能实例化感知后置处理器

    • 合并Bean定义信息后置处理器

    1. 获取所有的,后置处理器都默认可以通过、接口来执行优先级

    2. 先注册优先级接口的

      把每一个添加到中,

    3. 再注册接口的

    4. 最后注册没有实现任何优先级接口的

    5. 最终注册

    6. 注册一个,来在Bean创建完成后检查是否是,如果是就添加组件

初始化MessageSource

国际化

  1. :初始化组件(做国际化功能;消息绑定,消息解析)

    1. 获取

    2. 看容器中是否有id为的,类型是的组件,如果有赋值给,如果没有自己创建一个

      :取出国际化配置文件中的某个key的值;能按照区域信息获取

    3. 把创建好的注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入

初始化事件派发器、监听器

  1. :初始化事件派发器

    1. 获取

    2. 从中获取的

    3. 如果上一步没有配置,就创建一个

    4. 将创建的添加到中,以后其他组件直接自动注入

  2. :留给子容器(子类)

    1. 子类重写这个方法,在容器刷新的时候可以自定义逻辑;

  3. :给容器中将所有项目里面的注册进来;

    1. 从容器中拿到所有的

    2. 将每个监听器添加到事件派发器中

    3. 派发之前步骤产生的事件

创建Bean准备、完成

有代理对象就用,没有就创建,然后在初始化前后准备各种后置处理器,创建完成后放入各种Map

  1. :初始化所有剩下的单实例bean

    • 先触发:

    • 如果有返回值,触发:

    1. 获取容器中的所有Bean,依次进行初始化和创建对象

    2. 获取Bean的定义信息:

    3. 判断Bean不是抽象的,是单实例的,不是懒加载

    4. 这个就是平时测试类中用到的

    5. 先获取缓存中保存的单实例Bean。,如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)

      可以从属性获取到

    6. 缓存中获取不到,开始Bean的创建对象流程,使用

    7. 标记当前bean已经被创建

    8. 获取Bean的定义信息

    9. 【获取当前Bean依赖的其他Bean,,如果有按照就getBean()把依赖的Bean先创建出来】

    10. 启动单实例Bean的创建流程

    11. 【创建Bean实例】:

      利用工厂方法或者对象的构造器创建出Bean实例

    12. 调用的

    13. 【Bean属性赋值】

      赋值之前:

      开始赋值:

    14. 【Bean初始化】:

    15. 注册Bean的销毁方法

    16. 应用Bean属性的值;为属性利用setter方法等进行赋值:

    17. 拿到后置处理器:

      实例化后的后处理(对应上面(8.2))

    18. 拿到后置处理器:

      后处理属性值

    19. 是否是接口的实现;执行接口规定的初始化

    20. 是否自定义初始化方法

    21. 【执行Aware接口方法】:执行接口的方法,如

    22. 【在初始化之前应用 BeanPostProcessors】

    23. 【执行初始化方法】

    24. 【在初始化之后应用 BeanPostProcessors】

    25. 进入匿名类的方法(可以打断点进入)

    26. :让先拦截返回代理对象

      【提前执行,就是在AOP中先于执行的那个组件】

    27. 如果前面的没有返回代理对象,调用第4步创建Bean

    28. :创建Bean

    29. 将创建的Bean添加到缓存中

    30. 判断是否是,是否是实现接口的Bean

    31. 如果不是工厂Bean。利用:创建对象

    32. :初始化剩下的单实例bean

ioc容器就是这些Map,很多的Map里面保存了单实例Bean,环境信息...

所有Bean都利用getBean创建完成以后:检查所有的Bean是否是接口的,如果是,就执行

容器创建完成

  1. :完成的初始化创建工作,IOC容器就创建完成

    1. 默认从容器中找是否有的组件【】;

    2. 如果没有;

    3. 加入到容器

      写一个的实现类,可以在的生命周期、处拦截

    4. :初始化和生命周期有关的后置处理器:

    5. 拿到前面定义的生命周期处理器(),回调

    6. :发布容器刷新完成事件

编程笔记 » Spring注解开发,Spring容器创建概述

赞同 (73) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽