深入理解Spring源码之IOC 扩展原理BeanFactoryPostProcessor和事件监听ApplicationListener

简介: 深入理解Spring源码之IOC 扩展原理BeanFactoryPostProcessor和事件监听ApplicationListener

2.BeanFactoryPostProcessor

一个好的框架必备的特性至少得有开闭原则,可扩展性BeanFactoryPostProcessor也是Spring可扩展性的一个体现,我们读一下这个接口的源码

public interface BeanFactoryPostProcessor {
    /**
     * Modify the application context's internal bean factory after its standard
     * initialization. All bean definitions will have been loaded, but no beans
     * will have been instantiated yet. This allows for overriding or adding
     * properties even to eager-initializing beans.
     * @param beanFactory the bean factory used by the application context
     * @throws org.springframework.beans.BeansException in case of errors
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

允许我们在工厂里所有的bean被加载进来后但是还没初始化前,对所有bean的属性进行修改也可以add属性值。

bean工厂后置处理器—>构造方法—>init-method。

3、ApplicationListener

3.1、测试代码:

package com.atguigu.ext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.atguigu.bean.Blue;
@ComponentScan("com.atguigu.ext")
@Configuration
public class ExtConfig {
  @Bean
  public Blue blue(){
    return new Blue();
  }
}

 

import org.junit.Test;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.atguigu.ext.ExtConfig;
public class IOCTest_Ext {
  @Test
  public void test01(){
    AnnotationConfigApplicationContext applicationContext  = new AnnotationConfigApplicationContext(ExtConfig.class);
    //发布事件;
    applicationContext.publishEvent(new ApplicationEvent(new String("我发布的时间")) {
    });
    applicationContext.close();
  }
}

 

3.2、ApplicationListener的应用

ApplicationListener:监听容器中发布的事件。事件驱动模型开发;

       public interface ApplicationListener<E extends ApplicationEvent>

         监听 ApplicationEvent 及其下面的子事件;

 

      步骤:

         1)、写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类)

             @EventListener;

             原理:使用EventListenerMethodProcessor处理器来解析方法上的@EventListener;

 

         2)、把监听器加入到容器;

         3)、只要容器中有相关事件的发布,我们就能监听到这个事件;

                 ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;

                 ContextClosedEvent:关闭容器会发布这个事件;

         4)、发布一个事件:

                 applicationContext.publishEvent();

3.3、ApplicationListener的原理

  【事件发布流程】:

    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方法;

注解:为了便于理解下面只保留了最核心的源码,只在关键的调用地方打中文注释

public abstract class AbstractApplicationContext extends DefaultResourceLoader
    implements ConfigurableApplicationContext, DisposableBean {
  @Override
  public void publishEvent(ApplicationEvent event) {
    publishEvent(event, null);
  }
  protected void publishEvent(Object event, ResolvableType eventType) {
    ApplicationEvent applicationEvent;
    if (event instanceof ApplicationEvent) {
      applicationEvent = (ApplicationEvent) event;
    }
    else {
      applicationEvent = new PayloadApplicationEvent<Object>(this, event);
      if (eventType == null) {
        eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
      }
    }
    if (this.earlyApplicationEvents != null) {
      this.earlyApplicationEvents.add(applicationEvent);
    }
    else {
      getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    }
  }
}
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
  private Executor taskExecutor;
  private ErrorHandler errorHandler;
  @Override
  public void multicastEvent(ApplicationEvent event) {
    multicastEvent(event, resolveDefaultEventType(event));
  }
  @Override
  public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
      Executor executor = getTaskExecutor();
      if (executor != null) {
        executor.execute(new Runnable() {
          @Override
          public void run() {
            invokeListener(listener, event);
          }
        });
      }
      else {
        invokeListener(listener, event);
      }
    }
  }
}

3.4、 @EventListener

3.4.1、基于注解的方式创建监听器:

import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
@Service
public class UserInfoService {
  @EventListener(classes={ApplicationEvent.class})
  public void listen(ApplicationEvent event){
    System.out.println("UserService。。监听到的事件:"+event);
  }
}

3.4.2 @EventListener注解原理

原理:使用EventListenerMethodProcessor处理器来解析方法上的@EventListener;

再看SmartInitializingSingleton  这个类的原理即可

public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware

SmartInitializingSingleton 原理:->执行这个方法afterSingletonsInstantiated();

afterSingletonsInstantiated();是在所有bean初始化完成之后调用的,

断点在EventListenerMethodProcessor.afterSingletonsInstantiated()方法上查看执行流程

1)、ioc容器创建对象并refresh();

2)、finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean;

      1)、DefaultListableBeanFactory.preInstantiateSingletons()->先创建所有的单实例bean;getBean();

      2)、获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;如果是就调用afterSingletonsInstantiated();

 

 public abstract class AbstractApplicationContext extends DefaultResourceLoader
    implements ConfigurableApplicationContext, DisposableBean {
  //ioc容器创建对象并refresh();
  @Override
  public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
      prepareRefresh();
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      prepareBeanFactory(beanFactory);
      try {
        postProcessBeanFactory(beanFactory);
        invokeBeanFactoryPostProcessors(beanFactory);
        registerBeanPostProcessors(beanFactory);
        initMessageSource();
        initApplicationEventMulticaster();
        onRefresh();
        registerListeners();
        // 初始化剩下的单实例bean
        finishBeanFactoryInitialization(beanFactory);
        finishRefresh();
      }
      catch (BeansException ex) {
        destroyBeans();
        cancelRefresh(ex);
        throw ex;
      }
      finally {
        resetCommonCaches();
      }
    }
  }
}
public abstract class AbstractApplicationContext extends DefaultResourceLoader
    implements ConfigurableApplicationContext, DisposableBean {
  protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    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(new StringValueResolver() {
        @Override
        public String resolveStringValue(String strVal) {
          return getEnvironment().resolvePlaceholders(strVal);
        }
      });
    }
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
    }
    beanFactory.setTempClassLoader(null);
    beanFactory.freezeConfiguration();
                //先创建所有的单实例bean
    beanFactory.preInstantiateSingletons();
  }
}
@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
    implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
  @Override
  public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isDebugEnabled()) {
      this.logger.debug("Pre-instantiating singletons in " + this);
    }
    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
    for (String beanName : beanNames) {
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
        if (isFactoryBean(beanName)) {
          final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
          boolean isEagerInit;
          if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
            isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
              @Override
              public Boolean run() {
                return ((SmartFactoryBean<?>) factory).isEagerInit();
              }
            }, getAccessControlContext());
          }
          else {
            isEagerInit = (factory instanceof SmartFactoryBean &&
                ((SmartFactoryBean<?>) factory).isEagerInit());
          }
          if (isEagerInit) {
            getBean(beanName);
          }
        }
        else {
          getBean(beanName);
        }
      }
    }
    for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
                       //获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;
      if (singletonInstance instanceof SmartInitializingSingleton) {
        final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
        if (System.getSecurityManager() != null) {
          AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
              smartSingleton.afterSingletonsInstantiated();
              return null;
            }
          }, getAccessControlContext());
        }
        else { 
                                         //如果是就调用afterSingletonsInstantiated();
          smartSingleton.afterSingletonsInstantiated();
        }
      }
    }
  }
}

待续。。。


相关文章
|
2天前
|
安全 Java 开发者
在Spring框架中,IoC和AOP是如何实现的?
【4月更文挑战第30天】在Spring框架中,IoC和AOP是如何实现的?
10 0
|
2天前
|
Java 测试技术 开发者
Spring IoC容器通过依赖注入机制实现控制反转
【4月更文挑战第30天】Spring IoC容器通过依赖注入机制实现控制反转
9 0
|
2天前
|
XML Java 程序员
什么是Spring的IoC容器?
【4月更文挑战第30天】什么是Spring的IoC容器?
7 0
|
2天前
|
设计模式 安全 Java
【初学者慎入】Spring源码中的16种设计模式实现
以上是威哥给大家整理了16种常见的设计模式在 Spring 源码中的运用,学习 Spring 源码成为了 Java 程序员的标配,你还知道Spring 中哪些源码中运用了设计模式,欢迎留言与威哥交流。
|
3天前
|
Java 中间件 微服务
Spring Boot自动装配原理以及实践(下)
Spring Boot自动装配原理以及实践(下)
13 0
|
3天前
|
Java Spring 容器
Spring Boot自动装配原理以及实践(上)
Spring Boot自动装配原理以及实践(上)
7 0
|
4天前
|
Java Spring 容器
【Spring系列笔记】IOC与DI
IoC 和 DI 是面向对象编程中的两个相关概念,它们主要用于解决程序中的依赖管理和解耦问题。 控制反转是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入和依赖查找。
20 2
|
5天前
|
Java 测试技术 数据库连接
Spring中ioc的优点
总之,Spring中的IoC提供了一种更加灵活、可维护、可测试和可扩展的方式来管理组件之间的依赖关系,从而提高了应用程序的质量和可维护性。这使得开发人员能够更专注于业务逻辑而不是底层的技术细节。
23 1
|
5天前
|
设计模式 存储 Java
手写spring第二章-运用设计模式编写可扩展的容器
手写spring第二章-运用设计模式编写可扩展的容器
8 0
|
5天前
|
XML 缓存 Java
Spring核心功能IOC详解
Spring核心功能IOC详解
17 0
Spring核心功能IOC详解