美文网首页
Spring注解之七扩展原理

Spring注解之七扩展原理

作者: Java及SpringBoot | 来源:发表于2019-11-27 11:05 被阅读0次

    个人专题目录

    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<E extends ApplicationEvent>,监听 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注解之七扩展原理

          本文链接:https://www.haomeiwen.com/subject/rwpywctx.html