Spring5.0源码深度解析之容器的功能扩展

版权所有:https://my.oschina.net/u/3995125,禁止转载

写在前面:本篇源码分析文章:适合有三年开发经验的IT人员(中高级水平)参考,小白就别浪费自己宝贵的时间啦~~~

容器的功能扩展

前期准备:

同样,我们还是以 AnnotationConfigApplicationContext 作为切入点,开始对整体功能进行分析。

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();
   register(annotatedClasses);
   refresh();
}

一:创建IOC容器

进入this();

public AnnotationConfigApplicationContext() {
   this.reader = new AnnotatedBeanDefinitionReader(this);
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}

先执行父类的初始化方法,创建IOC容器

public GenericApplicationContext() {
   this.beanFactory = new DefaultListableBeanFactory();
}

2.进入AnnotatedBeanDefinitionReader方法执行初始化方法创建BeanDefinition读取器

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
   Assert.notNull(environment, "Environment must not be null");
   this.registry = registry;
   this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
   AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

AnnotationConfigUtils获取所有BeanPostProcessor的Bean,把下面6个对象注入到IOC容器中了

这里用到了CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME 、AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME 等几个常量

常量

对应的BeanPostProcessor

对应的注解

CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME

ConfigurationClassPostProcessor

@Configuration

AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME

AutowiredAnnotationBeanPostProcessor

@AutoWired

REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME

RequiredAnnotationBeanPostProcessor

@Required

COMMON_ANNOTATION_PROCESSOR_BEAN_NAME

CommonAnnotationBeanPostProcessor

@javax.annotation.PostConstruct、@javax.annotation.PreDestroy

等等,还有几个,就不列了。

3.进入ClassPathBeanDefinitionScanner方法创建classPath下扫描器

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
      Environment environment, @Nullable ResourceLoader resourceLoader) {

   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
   this.registry = registry;

   if (useDefaultFilters) {
      registerDefaultFilters();
   }
   setEnvironment(environment);
   setResourceLoader(resourceLoader);
}

二:注册配置类

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();
   register(annotatedClasses);
   refresh();
}
public void register(Class<?>... annotatedClasses) {
   Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
   this.reader.register(annotatedClasses);
}
public void register(Class<?>... annotatedClasses) {
   for (Class<?> annotatedClass : annotatedClasses) {
      registerBean(annotatedClass);
   }
}
public void registerBean(Class<?> annotatedClass) {
   doRegisterBean(annotatedClass, null, null, null);
}
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

   AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);//创建BeanDefinition对象
   if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {    //处理 @Condition注解
      return;
   }

   abd.setInstanceSupplier(instanceSupplier); //设置对象是单例模式还是多例模式,默认单例
   ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
   abd.setScope(scopeMetadata.getScopeName());    //获取BeanName,设置的化就采用默认值,否则类名第一个字母小写
   String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

   AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); //处理Lazy,primary等注解
   .....

   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//判断对象是否需要代理,不需要直接返回,需要的化,重新创建BeanDefinition加入代理的信息
   BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);    //注册配置类到IOC容器
}

扩展功能

进入 refresh()方法,可以说refresh函数中包括了几乎ApplicationContext中提供的全部功能,而且此函数中逻辑非常清晰明了。

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();
   register(annotatedClasses);
   refresh();
}
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      prepareRefresh();//准备刷新上下文环境

      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//初始化BeanFacgtory

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);//初始化BeanFactory进行各种功能填充

      try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);//子类覆盖方法做额外的处理

         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);//激活各种BeanFactory处理器

         // Register bean processors that intercept bean creation.
         registerBeanPostProcessors(beanFactory);//注册拦截Bean创建的Bean处理器,这里只是注册,真正的调用是在getBean的时候

         // Initialize message source for this context.
         initMessageSource();//为上下文初始化Message源,集不同语言的消息体,国际化处理

         // Initialize event multicaster for this context.
         initApplicationEventMulticaster();//初始化应用消息广播器,并放入applicationEventMulticaster bean中

         // Initialize other special beans in specific context subclasses.
         onRefresh();//留给子类来初始化其它的Bean

         // Check for listener beans and register them.
         registerListeners();//在所有注册的Bean中查找Listener bean,注册到消息广播器中

         // Instantiate all remaining (non-lazy-init) singletons.
         finishBeanFactoryInitialization(beanFactory);//初始化剩下的单实例(非惰性)

         // Last step: publish corresponding event.
         finishRefresh();//完成刷新过程,通知生命周期处理器 LifecycleProcessor刷新过程,同时发出 ContextRefreshedEvent 通知别人
      }

      catch (BeansException ex) {
       
         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();//销毁Bean

         // Reset 'active' flag.
         cancelRefresh(ex);//更改活跃状态

         // Propagate exception to caller.
         throw ex;
      }
   }
}

准备刷新上下文环境

prepareRefresh();函数主要作用是对系统属性及环境变量的初始化及验证

/**
 * Prepare this context for refreshing, setting its startup date and
 * active flag as well as performing any initialization of property sources.
 */
protected void prepareRefresh() {
   this.startupDate = System.currentTimeMillis();
   this.closed.set(false);
   this.active.set(true);

   if (logger.isInfoEnabled()) {
      logger.info("Refreshing " + this);
   }

   // Initialize any placeholder property sources in the context environment
   initPropertySources();//留给子类覆盖

   // Validate that all properties marked as required are resolvable
   // see ConfigurablePropertyResolver#setRequiredProperties
   getEnvironment().validateRequiredProperties();//验证需要的属性文件是否都已经放入环境中去了

   // Allow for the collection of early ApplicationEvents,
   // to be published once the multicaster is available...
   this.earlyApplicationEvents = new LinkedHashSet<>();
}

initPropertySources是空的,没有任何逻辑处理,getEnvironment().validateRequiredProperties()也是因为没有需要验证的属性而没有做任何处理,然而这两个方法作用还是很大的。那么该怎么用呢?

1.initPropertySources正符合Spring的开放式结构设计,给用户最大的扩展Spring的能力。 2.validateRequiredProperties则是对属性进行验证,那么如何验证呢?我们举个例子来说明下:

public class MyAnnotationConfigApplication extends AnnotationConfigApplicationContext {
    public MyAnnotationConfigApplication(Class<?>... annotatedClasses){
        super(annotatedClasses);
    }
    @Override
    protected void initPropertySources(){
        //添加验证要求
        getEnvironment().setRequiredProperties("VAR");
    }
}

我们自定义了继承自AnnotationConfigApplicationContext的MyAnnotationConfigApplication,并重写了initPropertySources方法,在方法中添加了我们的个性化需求,那么在验证的时候也就是程序走到 validateRequiredProperties()代码的时候,我们还需要替换掉原有的AnnotationConfigApplicationContext为我们自定义的MyAnnotationConfigApplication。

public class Test002 {
    public static void main(String[] args) {
       ApplicationContext context = new MyAnnotationConfigApplication(MyConfig.class);
       Object payEntity = context.getBean("payEntity");
       System.out.println(payEntity);
    }
}

如果系统并没有检测到对应的VAR环境变量,那么就会抛出异常:

初始化BeanFacgtory

obtainFreshBeanFactory()方法的作用是:经过这个方法,ApplicationContext就已经拥有了BeanFactory的全部功能。

/**
 * Tell the subclass to refresh the internal bean factory.
 * @return the fresh BeanFactory instance
 * @see #refreshBeanFactory()
 * @see #getBeanFactory()
 */
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    //初始化BeanFactory
   refreshBeanFactory();
    //返回当前实体的BeanFactory属性
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   if (logger.isDebugEnabled()) {
      logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
   }
   return beanFactory;
}

方法中将核心实现委托给了refreshBeanFactory:

/**
 * This implementation performs an actual refresh of this context's underlying
 * bean factory, shutting down the previous bean factory (if any) and
 * initializing a fresh bean factory for the next phase of the context's lifecycle.
 */
@Override
protected final void refreshBeanFactory() throws BeansException {
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      DefaultListableBeanFactory beanFactory = createBeanFactory();//创建DefaultListableBeanFactory 
      beanFactory.setSerializationId(getId());//序列化id
      customizeBeanFactory(beanFactory);//定制BeanFactory,设置相关属性,是否允许循环依赖,是否允许覆盖
      loadBeanDefinitions(beanFactory);//加载BeanDefinition
      synchronized (this.beanFactoryMonitor) {
         this.beanFactory = beanFactory;
      }
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

1.定制BeanFactory

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    //如果属性不为空,则设置给beanFactory对象相应属性,此属性的含义是:是否允许覆盖同名称的不同定义的对象
   if (this.allowBeanDefinitionOverriding != null) {
      beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
   }
    //如果属性不为空,设置给beanFactory对象相应的属性,这块属性的含义是:是否允许Bean之间存在循环依赖
   if (this.allowCircularReferences != null) {
      beanFactory.setAllowCircularReferences(this.allowCircularReferences);
   }
}

对于允许覆盖和允许循环依赖的设置这里只是进行了非空判断,如果不为空的化要进行设置,但是这里没有设置,所以还是那个套路,使用子类覆盖方法。

public class MyAnnotationConfigApplication extends AnnotationConfigApplicationContext {
    public MyAnnotationConfigApplication(Class<?>... annotatedClasses){
        super(annotatedClasses);
    }
    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory){
        super.setAllowBeanDefinitionOverriding(false);//是否允许覆盖同名称的不同定义的对象
        super.setAllowCircularReferences(false);//是否允许Bean之间存在循环依赖
    }
}

2.加载BeanDefinition

/**
 * Loads the bean definitions via an XmlBeanDefinitionReader.
 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
 * @see #initBeanDefinitionReader
 * @see #loadBeanDefinitions
 */
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   // Create a new XmlBeanDefinitionReader for the given BeanFactory.
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);//为指定的beanFactory创建XmlBeanDefinitionReader

   // Configure the bean definition reader with this context's
   // resource loading environment.
   beanDefinitionReader.setEnvironment(this.getEnvironment());//对beanDefinitionReader进行环境变量的设置
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   // Allow a subclass to provide custom initialization of the reader,
   // then proceed with actually loading the bean definitions.
   initBeanDefinitionReader(beanDefinitionReader);//进行设置可以覆盖
   loadBeanDefinitions(beanDefinitionReader);
}

在初始化了DefaultListableBeanFactoryXmlBeanDefinitionReader后就可以进行配置文件的读取了

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
   Resource[] configResources = getConfigResources();
   if (configResources != null) {
      reader.loadBeanDefinitions(configResources);
   }
   String[] configLocations = getConfigLocations();
   if (configLocations != null) {
      reader.loadBeanDefinitions(configLocations);
   }
}
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
   Assert.notNull(resources, "Resource array must not be null");
   int counter = 0;
   for (Resource resource : resources) {
      counter += loadBeanDefinitions(resource);
   }
   return counter;
}

经过此步骤,类型DefaultListableBeanFactory的变量beanFactory已经包含了所有已经解析好的配置

功能扩展

进入函数prepareBeanFactory前,Spring已经完成了对配置的解析,而ApplicationContext在功能上的扩展也由此展开。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // Tell the internal bean factory to use the context's class loader etc.
   beanFactory.setBeanClassLoader(getClassLoader());//设置BeanFactory的classLoader为当前context的classLoader
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));//设置beanFactory的表达式语言处理器,默认可以使用#{bean.xx}的形式来调用相关的属性值。
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));//为BeanFactory增加了一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具

   // Configure the bean factory with context callbacks.
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));//添加BeanPostProcessor

    //设置了几个忽略自定装配的接口
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    //设置了几个自定装配的规则
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // Register early post-processor for detecting inner beans as ApplicationListeners.
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // 增加了对AspectJ的支持
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   // 添加了默认的系统环境bean
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}

上面函数中主要进行了几个方面的扩展

  • 增加了对SpEL语言的支持
  • 增加对属性编辑器的支持
  • 增加了对一些内置类,比如实现了Aware接口的类信息注入
  • 设置了依赖功能可忽略接口
  • 注册一些固定依赖的属性
  • 增加了AspectJ的支持,后面再去分析
  • 将相关环境变量及属性注册以单例模式注册

上面可扩展功能很多,我就不一一介绍了,下面我们来挑几个我们感兴趣的函数来分析下:

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)),其主要目的就是注册个BeanPostProcessor,而真正的逻辑还是在ApplicationContextAwareProcessor中

ApplicationContextAwareProcessor实现了BeanPostProcessor接口,我们回顾下之前讲解的内容,在Bean实例化的时候,也就是Spring激活Bean的init-method方法前后, 会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法。所以我们也就去看看ApplicationContextAwareProcessor对这两个方法的实现。

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
   return bean;
}

对于后置处理器BeanPostProcessor的后置处理方法中并没有做任何逻辑处理,那么我们转向后置处理器的前置处理

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
   AccessControlContext acc = null;

   if (System.getSecurityManager() != null &&
         (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
               bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
               bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
      acc = this.applicationContext.getBeanFactory().getAccessControlContext();
   }

   if (acc != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareInterfaces(bean);
         return null;
      }, acc);
   }
   else {
      invokeAwareInterfaces(bean);
   }

   return bean;
}
private void invokeAwareInterfaces(Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof EnvironmentAware) {
         ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
      }
      if (bean instanceof EmbeddedValueResolverAware) {
         ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
      }
      if (bean instanceof ResourceLoaderAware) {
         ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
      }
      if (bean instanceof ApplicationEventPublisherAware) {
         ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
      }
      if (bean instanceof MessageSourceAware) {
         ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
      }
      if (bean instanceof ApplicationContextAware) {
         ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
      }
   }
}

postProcessBeforeInitialization方法中调用了invokeAwareInterfaces。从invokeAwareInterfaces方法中,我们或许已经差不多知道了Spring的用意,实现了这些Aware接口的Bean在被初始化后,可以取到一些对于的资源。

示例:

@Component
public class MyApplicationContext implements ApplicationContextAware {
    /**
     * spring底层中为什么能够实现ApplicationContextAware接口 就能够拿到ApplicationContext
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("applicationContext:>>>>"+applicationContext);
    }
}

BeanFactory的后处理

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

注册BeanPostProcessor

我们自定义MyInstantiationAwareBeanPostProcessor实现BeanPostProcessor 接口

@Component
public class MyInstantiationAwareBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization....");
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization....");
        return null;
    }
}
@Import(MyInstantiationAwareBeanPostProcessor.class)

结果输出:每次初始化一个Bean就会在之前和之后处理一些自定义逻辑

postProcessBeforeInitialization.... 4.bean init方法执行.. postProcessAfterInitialization....

初始化ApplicationEventMulticaster

/**
 * Initialize the ApplicationEventMulticaster.
 * Uses SimpleApplicationEventMulticaster if none defined in the context.
 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
 */
protected void initApplicationEventMulticaster() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
      this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
      if (logger.isDebugEnabled()) {
         logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
      }
   }
   else {
      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
      if (logger.isDebugEnabled()) {
         logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
               APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
               "': using default [" + this.applicationEventMulticaster + "]");
      }
   }
}

进入SimpleApplicationEventMulticaster找到这段代码:

public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
   ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
   for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
      Executor executor = getTaskExecutor();
      if (executor != null) {
         executor.execute(() -> invokeListener(listener, event));
      }
      else {
         invokeListener(listener, event);
      }
   }
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
   ErrorHandler errorHandler = getErrorHandler();
   if (errorHandler != null) {
      try {
         doInvokeListener(listener, event);
      }
      catch (Throwable err) {
         errorHandler.handleError(err);
      }
   }
   else {
      doInvokeListener(listener, event);
   }
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
        ....
      listener.onApplicationEvent(event);
}

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

注册监听器

进入registerListeners函数,开始注册监听器:

protected void registerListeners() {

   for (ApplicationListener<?> listener : getApplicationListeners()) {//硬编码方式注册的监听器处理
      getApplicationEventMulticaster().addApplicationListener(listener);
   }

   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);//配置文件注册的监听器处理
   for (String listenerBeanName : listenerBeanNames) {
      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
   }
   Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
   this.earlyApplicationEvents = null;
   if (earlyEventsToProcess != null) {
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
         getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
   }
}

Application下抽象子类ApplicationContextEvent的下面有4个已经实现好的事件

  • ContextClosedEvent(容器关闭时)
  • ContextRefreshedEvent(容器刷新时)
  • ContextStartedEvent(容器启动时候)
  • ContextStoppedEvent(容器停止的时候)

同样,这四个事件都继承了ApplicationEvent,如果我们想自定义事件,也可以通过继承ApplicationEvent来实现

使用示例:

1.定义监听事件

public class TestEvent extends ApplicationEvent {
    private String msg;
    public TestEvent(Object source){
        super(source);
    }
    public TestEvent(Object source,String msg){
        super(source);
        this.msg=msg;
    }
    public void print(){
        System.out.println(msg);
    }
}

2.定义监听器

public class TestListener implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof TestEvent){
            TestEvent testEvent= (TestEvent)event;
            testEvent.print();
        }
    }
}

注入容器

@Import(TestListener.class)

测试:

public class Test001 {

    public static void main(String[] args) {
        /**
         * IOC容器初始化单例对象都是循环遍历调用getBean方法
         */
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        TestEvent testEvent = new TestEvent("hello", "hello word");
        applicationContext.publishEvent(testEvent);
    }
}

输出结果:

我们在补充一个注解形式的例子:

public class TestEvent extends ApplicationEvent {

    private String msg;
    public TestEvent(Object source){
        super(source);
    }
    public TestEvent(Object source,String msg){
        super(source);
        this.msg=msg;
    }
    public void print(){
        System.out.println("注册监听器..,TestEvent....");
    }
}
@Component
public class MyAnnotationListener {

    @EventListener
    public String listener1(TestEvent event) {
        if (event instanceof TestEvent){
            TestEvent testEvent=event;
            testEvent.print();
        }
        return "xd";
    }
}
@Import(MyAnnotationListener.class)
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
MyAnnotationListener myAnnotationListener = new MyAnnotationListener();
applicationContext.publishEvent(myAnnotationListener.listener1(new TestEvent("jj")));

输出:

初始化非延迟加载单例

进入finishBeanFactoryInitialization函数初始化所有非懒加载Bean

/**
 * Finish the initialization of this context's bean factory,
 * initializing all remaining singleton beans.
 */
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(//定义转换器从String转为Date的方式,可以自己扩展,我就不多说了
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   beanFactory.freezeConfiguration();//冻结所有Bean的定义,说明注册的Bean定义将不被修改或处理。

   // Instantiate all remaining (non-lazy-init) singletons.
   beanFactory.preInstantiateSingletons();//初始化剩下的单实例(非惰性)
}

冻结配置

@Override
public void freezeConfiguration() {
   this.configurationFrozen = true;
   this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);

初始化非延迟加载

ApplicationContext实现的默认行为就是在启动时将所有单例bean提前进行实例化。提前实例化的好处是,在配置中任何错误就会立即被发现Z(否则的化,一旦出错,排除bug相当困难)。

public void preInstantiateSingletons() throws BeansException {
   if (this.logger.isDebugEnabled()) {
      this.logger.debug("Pre-instantiating singletons in " + this);
   }

   // Iterate over a copy to allow for init methods which in turn register new bean definitions.
   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   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((PrivilegedAction<Boolean>) () ->
                     ((SmartFactoryBean<?>) factory).isEagerInit(),
                     getAccessControlContext());
            }
            else {
               isEagerInit = (factory instanceof SmartFactoryBean &&
                     ((SmartFactoryBean<?>) factory).isEagerInit());
            }
            if (isEagerInit) {
               getBean(beanName);
            }
         }
         else {
            getBean(beanName);
         }
      }
   }

finishRefresh

在Spring中还提供了Lifecycle接口,Lifecycle接口中包含start/stop方法,实现此接口后Spring会保证在启动的时候调用其start方法开始生命周期,并且在spring关闭的时候调用stop方法来结束生命周期, 通常用来配置后台程序,在启动后一直运行(such as MQ进行轮询等)。

/**
 * Finish the refresh of this context, invoking the LifecycleProcessor's
 * onRefresh() method and publishing the
 * {@link org.springframework.context.event.ContextRefreshedEvent}.
 */
protected void finishRefresh() {
   // Clear context-level resource caches (such as ASM metadata from scanning).
   clearResourceCaches();

   // Initialize lifecycle processor for this context.
   initLifecycleProcessor();//当ApplicationContext启动或者停止时,会通过LifecycleProcessor来与所有声明的bean的周期做状态更新,而在LifecycleProcessor使用前需要初始化

   // Propagate refresh to lifecycle processor first.
   getLifecycleProcessor().onRefresh();//启动所有实现了Lifecycle接口的bean

   // Publish the final event.
   publishEvent(new ContextRefreshedEvent(this));//当完成ApplicationContext初始化的时候,要通过Spring中的事件发布机制来发出ContextRefreshedEvent监听事件,以保证对应的监听器可以做进一步的逻辑处理

   // Participate in LiveBeansView MBean, if active.
   LiveBeansView.registerApplicationContext(this);
}

到这里,我们就谈完了!!!

参考书籍:Spring源码深度解析

参考链接:http://www.mayikt.com

版权所有:https://my.oschina.net/u/3995125,禁止转载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券