Spring注解之七扩展原理

个人专题目录:

ActiviMQ专题

链路追踪

Dubbo专题

Docker专题

Git专题

Idea专题

Java阿里P6+必会专题

Java工具类

Kafka专题

Linux专题

Maven专题

Markdown专题

Mysql专题

Netty专题

Nginx专题

Openstack专题

Redis专题

Spring专题

SpringBoot专题

SpringCloud专题

Zookeeper专题

个人随笔专题

数据结构专题

单点登录专题

设计模式专题

架构优化专题


扩展原理-BeanFactoryPostProcessor

Spring容器标准初始化之后执行(BeanPostProcessor之前),此时bean还未创建

Spring容器初始化两大步

  • 加载保存和读取所有bean配置
  • 按照之前的配置创建bean

  • BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的
  1. BeanFactoryPostProcessor:beanFactory的后置处理器;
    1. 在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;
    2. 所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
  2. BeanFactoryPostProcessor原理:
    1. ioc容器创建对象
    2. invokeBeanFactoryPostProcessors(beanFactory);如何找到所有的BeanFactoryPostProcessor并执行他们的方法;
      1. 直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
      2. 在初始化创建其他组件前面执行

扩展原理-BeanDefinitionRegistryPostProcessor

BeanFactoryPostProcessor子类,可自定义添加bean定义

BeanDefinetionRegistry

BeanDefinetionBuilder

  • BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
    • postProcessBeanDefinitionRegistry();
    • 在所有bean定义信息将要被加载,bean实例还未创建的的 ;
    • 优先于BeanFactoryPostProcessor执行;
    • 利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件;
  1. 原理:
    1. ioc创建对象
    2. refresh()-》invokeBeanFactoryPostProcessors(beanFactory);
    3. 从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件。
      1. 依次触发所有的postProcessBeanDefinitionRegistry()方法
      2. 再来触发postProcessBeanFactory()方法BeanFactoryPostProcessor;
    4. 再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法

扩展原理-ApplicationListener用法

  • ApplicationListener:监听容器中发布的事件。事件驱动模型开发;
  • public interface ApplicationListener,监听 ApplicationEvent 及其下面的子事件;
  • 步骤:
    1. 写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类)@EventListener;原理:使用EventListenerMethodProcessor处理器来解析方法上的@EventListener;
    2. 把监听器加入到容器;
    3. 只要容器中有相关事件的发布,我们就能监听到这个事件;ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;ContextClosedEvent:关闭容器会发布这个事件;
    4. 发布一个事件:applicationContext.publishEvent();

扩展原理-ApplicationListener原理

  1. ContextRefreshedEvent事件:
    1. 容器创建对象:refresh();
    2. finishRefresh();容器刷新完成会发布ContextRefreshedEvent事件
  2. 自己发布事件;
  3. 容器关闭会发布ContextClosedEvent;

扩展原理-@EventListener与SmartInitializingSingleton

【事件发布流程】:

  1. publishEvent(new ContextRefreshedEvent(this));
    1. 获取事件的多播器(派发器):getApplicationEventMulticaster()
    2. multicastEvent派发事件:
    3. 获取到所有的ApplicationListener; for (final ApplicationListener listener : getApplicationListeners(event, type)) {}
      1. 如果有Executor,可以支持使用Executor进行异步派发;Executor executor = getTaskExecutor();
      2. 否则,同步的方式直接执行listener方法;invokeListener(listener, event);拿到listener回调onApplicationEvent方法;

【事件多播器(派发器)】

  1. 容器创建对象:refresh();
  2. initApplicationEventMulticaster();初始化ApplicationEventMulticaster;
    1. 先去容器中找有没有id=“applicationEventMulticaster”的组件;
    2. 如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster;

【容器中有哪些监听器】

  1. 容器创建对象:refresh();
  2. registerListeners();从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中;String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);//将listener注册到ApplicationEventMulticaster中;getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
  • SmartInitializingSingleton 原理:->afterSingletonsInstantiated();
    1. ioc容器创建对象并refresh();
    2. finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean;
      1. 先创建所有的单实例bean;getBean();
      2. 获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;如果是就调用afterSingletonsInstantiated();

2.4. Spring容器创建过程

Spring容器创建-BeanFactory预准备

Spring容器创建-执行BeanFactoryPostProcessor

Spring容器创建-注册BeanPostProcessors

Spring容器创建-初始化MessageSource

Spring容器创建-初始化事件派发器、监听器等

Spring容器创建-创建Bean准备

Spring容器创建-Bean创建完成

Spring容器创建-容器创建完成

Spring源码总结

  • 首先根据配置文件找到对应的包,读取包中的类,,找到所有含有@bean,@service等注解的类,利用反射解析它们,包括解析构造器,方法,属性等等,然后封装成各种信息类放到container(其实是一个map)里(ioc容器初始化)
  • 获取类时,首先从container中查找是否有这个类,如果没有,则报错,如果有,则通过构造器信息将这个类new出来
  • 如果这个类含有其他需要注入的属性,则进行依赖注入,如果有则还是从container找对应的解析类,new出对象,并通过之前解析出来的信息类找到setter方法(setter方法注入),然后用该方法注入对象(这就是依赖注入)。如果其中有一个类container里没找到,则抛出异常
  • 如果有嵌套bean的情况,则通过递归解析
  • 如果bean的scope是singleton,则会重用这个bean不再重新创建,将这个bean放到一个map里,每次用都先从这个map里面找。如果scope是session,则该bean会放到session里面。

你可能感兴趣的:(Spring注解之七扩展原理)