IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> spring ioc容器创建过程(4)事件广播与注册监听 -> 正文阅读

[Java知识库]spring ioc容器创建过程(4)事件广播与注册监听

Spring ioc容器创建过程(1)BeanFactory初始化
spring ioc容器创建过程(2)invokeBeanFactoryPostProcessors
spring ioc容器创建过程(3)registerBeanPostProcessors

前三篇文章主要讲了beanFacctory的初始化,bean的后置处理器与beanFactory的后置处理器,这篇文章主要来分析下剩余部分。

1、initMessageSource()

这部分主要是用于spring国际化的功能,因为不常用就暂时不分析了。

2、initApplicationEventMulticaster()

看名字就知道了,这部分主要是来初始化spring的事件广播器的。这里主要用了设计模式的观察者模式,通过ApplicationEventMulticaster事件广播器实现了监听器的注册,通过ApplicationEvent抽象类和ApplicationListener接口,可以实现事件的处理。

/**
 * 如果用户自定义了事件广播器,那么使用用户自定义的事件广播器。
 * 如果用户没有自定义事件广播器,那么使用默认的ApplicationEventMulticaster即SimpleApplicationEventMulticaster。
 *
 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
 */
protected void initApplicationEventMulticaster() {
    //获取初始化好后的beanFactory
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    //bean工厂是否有applicationEventMulticaster这个bean
   if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
      this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
      if (logger.isTraceEnabled()) {
         logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
      }
   } else {
       //否则就创建SimpleApplicationEventMulticaster类作为aplicationEventMulticaster的Bean
       //SimpleApplicationEventMulticaster是aplicationEventMulticaster接口的一个实现
      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
       beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
       if (this.logger.isTraceEnabled()) {
           this.logger.trace("No 'applicationEventMulticaster' bean, using [" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
       }
   }
}

可以推断, 当产生Spring 事件的时候会默认使用Simpl巳ApplicationEventMulticaster 的multicastEvent 来广播事件,遍历所有监昕器,并使用监昕器中的onApplicationEvent 方法来进行监昕器的处理。而对于每个监听器来说其实都可以获取到产生的事件,但是是否进行处理则由事件监听器来决定。

3、onRefresh()

模板方法,留给子类实现,像springboot就实现了其方法作为tomcat容器的启动。

4、registerListeners()

2的过程已经初始化了spring的事件广播器,通过registerListeners可以去注册监听器。注册好监听器后,广播会将对应的事件传递给监听器。

/**
 * Add beans that implement ApplicationListener as listeners.
 * Doesn't affect other listeners, which can be added without being beans.
 */
protected void registerListeners() {
   // 手动注册的监听器绑定到广播器
   for (ApplicationListener<?> listener : getApplicationListeners()) {
      getApplicationEventMulticaster().addApplicationListener(listener);
   }
   //取到容器里面的所有的监听器的名称,绑定到广播器
   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   for (String listenerBeanName : listenerBeanNames) {
      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
   }
   // 如果存在早期应用事件就直接发布(同时就把earlyApplicationEvents该字段置为null)
   Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
   this.earlyApplicationEvents = null;
   if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
         getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
   }
}

5、finishBeanFactoryInitialization(beanFactory)

实例化所有单例的非懒加载的Bean,并完成依赖注入。

/**
 * Finish the initialization of this context's bean factory,
 * initializing all remaining singleton beans.
 */
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // 初始化上下文的转换服务,ConversionService是一个类型转换接口,作用即处理自定义的转换类型
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }
   //主要用于注释属性值的解析
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }
   // 初始化 LoadTimeWeaverAwareBean 用于织入第三方模块,在 class 文件载入 JVM 的时候动态织入
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }
   //将临时类加载器设置为null
   beanFactory.setTempClassLoader(null);
   //冻结(缓存)所有的bean定义(ean definition),说明注册的bean 定义将不被修改或任何进一步的处理
   beanFactory.freezeConfiguration();
   //初始化剩下的单实例(非懒加载的)
   beanFactory.preInstantiateSingletons();
}

5.1、 DefaultListableBeanFactory#preInstantiateSingletons()

ApplicationContext 实现的默认行为就是在启动时将所有单例bean 提前进行实例化。提前实例化意味着作为初始化过程的一部分, ApplicationContext 实例会创建并配置所有的单例bean. 通常情况下这是一件好事,因为这样在配置中的任何错误就会即刻被发现。而这个实例化的过程就是在finishBeanFactorylnitialization 中完成的。这部分先简单过一下,下次开个专栏分析下。

@Override
public void preInstantiateSingletons() throws BeansException {
   if (logger.isTraceEnabled()) {
      logger.trace("Pre-instantiating singletons in " + this);
   }
   // 获取所有的beanName
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
   // 初始化所有的非懒加载的单例bean
   for (String beanName : beanNames) {
      //对bean定义进行合并,如bean中引入parent属性
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      // 不是抽象类,是单例的,不是懒加载的
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         // 如果是工厂Bean,那就会此工厂Bean放进去
         if (isFactoryBean(beanName)) {
            //如果是工厂bean,调用的时候再bean的名称前面添加前缀符号&
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
 
            //拿到对应的bean后再次判断bean是否是factoryBean
            if (bean instanceof FactoryBean) {
               FactoryBean<?> factory = (FactoryBean<?>) bean;
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged(
                        (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean<?>) factory).isEagerInit());
               }
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
         // 非FactoryBean初始化
         else {
            getBean(beanName);
         }
      }
   }
   //再次遍历beanNames,对实现了SmartInitializingSingleton接口的类实现处理,会调用到该bean的afterSingletonsInstantiated()方法。
   //在单例bean加载完成后,做一些事情
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
               .tag("beanName", beanName);
         SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            //native方法  不用做权限检查
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
         smartInitialize.end();
      }
   }
}

6、finishRefresh()

/**
 * Finish the refresh of this context, invoking the LifecycleProcessor's
 * onRefresh() method and publishing the
 * {@link org.springframework.context.event.ContextRefreshedEvent}.
 */
@SuppressWarnings("deprecation")
protected void finishRefresh() {
   // Clear context-level resource caches (such as ASM metadata from scanning).
   clearResourceCaches();
   //初始化生命周期管理器LifecycleProcessor
   initLifecycleProcessor();
   //启动所有实现了Lifecycle接口的bean
   getLifecycleProcessor().onRefresh();
   //发布刷新完成事件
   publishEvent(new ContextRefreshedEvent(this));
   if (!IN_NATIVE_IMAGE) {
      LiveBeansView.registerApplicationContext(this);
   }
}

到这里基本上spring ioc容器的初始化就结束了。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-05 17:11:57  更:2021-08-05 17:16:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/12 1:51:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码