Spring源码分析一:容器篇—refresh()

(一)BeanFactory与ApplicationContext容器

BeanFactory是加载Bean的基础基石,早期spring的实现是利用XmlBeanFactory来实现其基本功能,相对于ApplicationContext来说,缺少了很多扩展性。

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(“config/applicationContext.xml”));

ApplicationContext也是加载Bean的,是在BeanFactory基础之上增加更多扩展,利用ClassPathXmlApplicationContext实现spring,也是目前开发系统的首选。

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“config/applicationContext.xml”);

(二)ApplicationContext层次结构

ClassPathXmlApplicationContext

ClassPathXmlApplicationContext类主要类继承结构:
ClassPathXmlApplicationContext—》AbstractXmlApplicationContext—》AbstractRefreshableConfigApplicationContext—》AbstractRefreshableApplicationContext—》AbstractApplicationContext—》DefaultResourceLoader

ClassPathXmlApplicationContext实现接口结构:

(1)AbstractRefreshableConfigApplicationContext——》BeanNameAware,>InitializingBean——》Aware
(2)AbstractApplicationContext——》ConfigurableApplicationContext——ApplicationContext,Lifecycle, Closeable
(3)ApplicationContext(核心)——》EnvironmentCapable,ListableBeanFactory, HierarchicalBeanFactory, MessageSource,ApplicationEventPublisher, ResourcePatternResolver >>
(4) Closeable——》AutoCloseable
(5) ListableBeanFactory,HierarchicalBeanFactory——》BeanFactory

从ApplicationContext来继承关系来看。最终也是继承并实现了BeanFactory的所有功能,同时在AbstractApplicationContext中使用了大量的扩展方法,用于用户自行扩展,ApplicationContext本身也较之BeanFactory扩展了很多。

(三)容器刷新——refresh()

refresh()在spring源码中主要是在注解配置和xml文件配置上下文来调用,本文暂时分析XML配置启动上下文(ClassPathXmlApplicationContext)的方式来解读Spring容器。

1、ClassPathXmlApplicationContext根据配置文件构造容器

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);//内部构造器调用
}
public ClassPathXmlApplicationContext(
		String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
		throws BeansException {
	super(parent);//是否已存在容器,存在则增加,一般为null
	setConfigLocations(configLocations);//配置文件地址
	if (refresh) {//默认为true
		refresh();//开始构造容器ApplicationContext
	}
}

2、refresh()分析

refresh()方法定义在ConfigurableApplicationContext中,由AbstractApplicationContext抽象类实现,因ClassPathXmlApplicationContext单一且多次不断继承到了AbstractApplicationContext得以间接拥有该方法,里面高度封装了各步骤,逐一分析:

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		//准备刷新上下文环境
		prepareRefresh();

		//初始化BeanFactory并读取XML配置文件即解析XMl
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		//对BeanFactory进行功能填充
		prepareBeanFactory(beanFactory);
		try {
			//子类通过覆盖该方法进行自定义扩展,默认为空实现
			postProcessBeanFactory(beanFactory);

			//激活各种BeanFactory处理器
			invokeBeanFactoryPostProcessors(beanFactory);

			//将拦截到的Bean创建的Bean处理器注册,仅注册
			registerBeanPostProcessors(beanFactory);

			//为上下文初始化不同语言消息体,国际化处理
			initMessageSource();

			//初始化上下文消息广播,即监听器处理
			initApplicationEventMulticaster();

			//子类重写时自定义扩展,默认为空
			onRefresh();

			//在注册的bean中将监听器注册到消息广播器中
			registerListeners();

			//初始化bean常规饿汉式单实例bean即非惰性的bean
			finishBeanFactoryInitialization(beanFactory);

			//刷新完成通知器,通知生命周期处理器LifecycleProcessor刷新且发出ContextRefreshEvent通知
			finishRefresh();
		}catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);
			}
			//异常时将已创建好的bean销毁
			destroyBeans();

			//重置一些激活标志
			cancelRefresh(ex);
			throw ex;
		}finally {
			//重置一些启动完成后,不必要的缓存
			resetCommonCaches();
		}
	}
}

(四)容器刷新——refresh()详述

1、环境准备——prepareRefresh()

简述功能作用:主要是spring的开放性设计和系统变量(环境变量)的验证,虽然在prepareRefresh中都是空实现,其目的是用户可以通过子类重写时可以添加自己系统的业务逻辑。

代码如下:

 protected void prepareRefresh() {
        //获取系统时间和设置激活标志
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);
        if (logger.isDebugEnabled()) {
            if (logger.isTraceEnabled()) {
                logger.trace("Refreshing " + this);
            }
            else {
                logger.debug("Refreshing " + getDisplayName());
            }
        }

        //给子类覆盖去自行实现,默认为空,spring开放性设计
        initPropertySources();

        //验证需要的属性或文件是否都已放入spring环境中,例如需要使用系统变量的某个路径
        getEnvironment().validateRequiredProperties();

        //初始化部分属性,便于后面使用
        if (this.earlyApplicationListeners == null) {
            this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
        }else {
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }
        this.earlyApplicationEvents = new LinkedHashSet<>();
    }

2、加载BeanFactory——obtainFreshBeanFactory()

简述功能作用:加载BeanFactory是在AbstractApplicationContext中obtainFreshBeanFactory方法,期内主要是refreshBeanFactory()和getBeanFactory(),refreshBeanFactory()方法有AbstractRefreshableApplicationContext和GenericApplicationContext分别实现,本文中是AbstractRefreshableApplicationContext类去实现,refreshBeanFactory()方法的实现实际上就是BeanFactory的全部功能, 即通过XML解析并构建BeanDefinition,形成BeanFactory。
代码如下:
AbstractApplicationContext类:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	refreshBeanFactory();
	return getBeanFactory();
}

refreshBeanFactory()方法是由AbstractApplicationContext抽象类定义的抽象接口,委托给子类(可以是抽象类继承)去实现(重写),此处是AbstractRefreshableApplicationContext子类实现refreshBeanFactory方法,该方法是加载BeanFactory的核心。

@Override
    protected final void refreshBeanFactory() throws BeansException {
        //判断是否已存在BeanFactory,已存在则销毁创建好的bean和beanFactory
        if (hasBeanFactory()) {
            destroyBeans();//销毁创建好的bean
            closeBeanFactory();//置空beanFactory
        }
        try {
            //创建DefaultListableBeanFactory
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            //对当前beanFactory设置id,根据该id反序列化beanFactory对象
            beanFactory.setSerializationId(getId());
            //定制BeanFactory,主要是开启同名覆盖和支持循环依赖
            customizeBeanFactory(beanFactory);
            //设置DocumentReader和读取XML配置并解析为BeanDefinition,构造BeanFactory
            loadBeanDefinitions(beanFactory);
            this.beanFactory = beanFactory;
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

创建beanFactory的类型,使用子类DefaultListableBeanFactory去实例化BeanFactory接口,返回beanFactory实际类型:DefaultListableBeanFactory

   protected DefaultListableBeanFactory createBeanFactory() {
   		//是否有父类BeanFactory去初始化
        return new DefaultListableBeanFactory(getInternalParentBeanFactory());
    }

对bean开启同名覆盖和支持单例循环依赖,spring中本身是未设置这两个值,allowBeanDefinitionOverriding和allowCircularReferences是spring框架开放性设计的做法,通过子类去赋值后,customizeBeanFactory方法就可以进行设置。

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
      if (this.allowBeanDefinitionOverriding != null) {//根据子类是否被重写
          beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);//赋值是否开启同名覆盖
      }
      if (this.allowCircularReferences != null) {//根据子类是否被重写
          beanFactory.setAllowCircularReferences(this.allowCircularReferences);//设置是否支持单例循环依赖
      }
  }

loadBeanDefinitions此处分析的XML配置的解析方式,注解的后续会进行分析,本次分析AbstractXmlApplicationContext类负责来解析XMl配置文件并构建BeanDefinition,最终形成BeanFactory。

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    //创建beanDefinition的解析器XMLBeanDefinitionReader,为BeanFactory形成做基础工作
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    //对XML解析器XmlBeanDefinitionReader设置环境变量
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    //允许子类提供的xml解析器覆盖
    initBeanDefinitionReader(beanDefinitionReader);
    //构建BeanDefinition并形成BeanFactory
    loadBeanDefinitions(beanDefinitionReader);
}

根据XMl配置文件使用XML解析器去解析为BeanDefinition,最后将其设置到DefaultListableBeanFactory中,此时的ApplicationContext拥有了BeanFactory的所有基本功能。

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
       //根据初始化时的配置文件设置方式
       //是否为Resource类型设置的配置文件参数
       Resource[] configResources = getConfigResources();
       if (configResources != null) {
           reader.loadBeanDefinitions(configResources);//使用解析器去读取配置文件和设置到beanFactory变量中
       }
       //是否为String类型设置的配置文件参数
       String[] configLocations = getConfigLocations();
       if (configLocations != null) {
           reader.loadBeanDefinitions(configLocations);//使用解析器去读取配置文件和设置到beanFactory变量中
       }
   }

3、对BeanFactory功能填充——prepareBeanFactory(beanFactory)

主要增加了以下功能:增加SpEL语言的支持、对属性编辑器的支持、增加一些内置类、设置依赖功能可忽略的接口、注册几个固定依赖的属性、增加AspectJ的支持、将相关环境变量及属性注册以单例模式注册

 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //设置BeanFactory的类加载器为上下文的类加载器
        beanFactory.setBeanClassLoader(getClassLoader());

        //spring开启对SpEL语言的支持,SpEL使用#{bean.name}作为界定符,所有在大括号里面的字符都被认为是SpEL
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

        //为beanFactory增加一个默认的属性编辑器即bean属性的管理工具
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        //增加一个后置处理器ApplicationContextAwareProcessor
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

        //忽略一些自动装配的接口即spring在前面默认添加的
        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);

        //增加后置处理器ApplicationListenerDetector即监听器
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

        //增加AspectJ的支持
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            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());
        }
    }

(1)SpEL语言的支持

spring开启对SpEL语言的支持,SpEL使用#{bean.name}作为界定符,所有在大括号里面的字符都被认为是SpEL,使用如下:

 <bean id="ClassA" class="com.spring.service.ClassA" ></bean>
 
 <bean id="ClassB" class="com.spring.service.ClassB">
     <property name="classA" value="#{ClassA}"/>
 </bean>

在prepareBeanFactory中通过beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));——>注册语言解析器,Spring在Bean初始化的属性填充时会使用,即AbstractAutowireCapableBeanFactory——>populateBean中调用了applyPropertyValues(beanName, mbd, bw, pvs)方法。
applyPropertyValues会通过构造BeanDefinitionValueResolver类型实例valueResolver来进行属性值的解析,同时也是在这个步骤中一般通过AbstractBeanFactory中的evaluateBeanDefinitionString方法完成了SpEL的解析。该方法会判断语言解析器是否存在,主要是在解析Bean的依赖注入(DI)、完成bean的初始化和属性获取之后被使用。

 @Nullable
    protected Object evaluateBeanDefinitionString(@Nullable String value, @Nullable BeanDefinition beanDefinition) {
        if (this.beanExpressionResolver == null) {//判断语言解析器
            return value;
        }
        Scope scope = null;
        if (beanDefinition != null) {
            String scopeName = beanDefinition.getScope();
            if (scopeName != null) {
                scope = getRegisteredScope(scopeName);
            }
        }
        //调用解析器中的方法,在spring的expression包中
        return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
    }

(2)属性编辑器

spring的属性编辑器分为自定义属性编辑器和默认的属性编辑器,自定义的属性编辑器只需要继承PropertyEditorSupport,重写setAsText方法,然后通过XMl配置文件将自定义属性编辑器注册到spring(利用CustomEditorConfigurer),并在customEditors属性注入,自定义属性编辑器如下:

  public class FormatPropertyEditors extends PropertyEditorSupport {
        private String str;

        public void setStr(String str) {
            this.str = str;
        }
        @Override
        public void setAsText(String text) throws java.lang.IllegalArgumentException {
            SimpleDateFormat df = new SimpleDateFormat(str);
            try {
                Date d = df.parse(text);
                this.setValue(d);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

XML配置文件如下:

 <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="customEditors">
            <map>
                <entry key="java.util.Date">
                    <bean class="com.spring.test.FormatPropertyEditors">
                        <property name="str" value="yyyy-MM-dd"></property>
                    </bean>
                </entry>
            </map>
        </property>
    </bean>

beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
spring默认的注册属性编辑器时,使用了ResourceEditorRegistrar方法,其内部中核心方法registerCustomEditors是定义了java中常用的一些属性类型,AbstractBeanFactory——>registerCustomEditors中调用了PropertyEditorRegistry——>registerCustomEditors,ResourceEditorRegistrar是实现了PropertyEditorRegistry接口;在BeanDefinition转换为BeanWrapper后的属性填充时,其实现类BeanWrapperImpl也间接实现了PropertyEditorRegistrySupport——> PropertyEditorRegistry。 PropertyEditorRegistrySupport中存在一个重要的方法createDefaultEditors,定义了Java常用的属性。

private void createDefaultEditors() {
	this.defaultEditors = new HashMap<>(64);
	// Simple editors, without parameterization capabilities.
	// The JDK does not contain a default editor for any of these target types.
	this.defaultEditors.put(Charset.class, new CharsetEditor());
	this.defaultEditors.put(Class.class, new ClassEditor());
	this.defaultEditors.put(Class[].class, new ClassArrayEditor());
	this.defaultEditors.put(Currency.class, new CurrencyEditor());
	this.defaultEditors.put(File.class, new FileEditor());
	this.defaultEditors.put(InputStream.class, new InputStreamEditor());
	this.defaultEditors.put(InputSource.class, new InputSourceEditor());
	this.defaultEditors.put(Locale.class, new LocaleEditor());
	this.defaultEditors.put(Path.class, new PathEditor());
	this.defaultEditors.put(Pattern.class, new PatternEditor());
	this.defaultEditors.put(Properties.class, new PropertiesEditor());
	this.defaultEditors.put(Reader.class, new ReaderEditor());
	this.defaultEditors.put(Resource[].class, new ResourceArrayPropertyEditor());
	this.defaultEditors.put(TimeZone.class, new TimeZoneEditor());
	this.defaultEditors.put(URI.class, new URIEditor());
	this.defaultEditors.put(URL.class, new URLEditor());
	this.defaultEditors.put(UUID.class, new UUIDEditor());
	this.defaultEditors.put(ZoneId.class, new ZoneIdEditor());

	// Default instances of collection editors.
	// Can be overridden by registering custom instances of those as custom editors.
	this.defaultEditors.put(Collection.class, new CustomCollectionEditor(Collection.class));
	this.defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
	this.defaultEditors.put(SortedSet.class, new CustomCollectionEditor(SortedSet.class));
	this.defaultEditors.put(List.class, new CustomCollectionEditor(List.class));
	this.defaultEditors.put(SortedMap.class, new CustomMapEditor(SortedMap.class));

	// Default editors for primitive arrays.
	this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
	this.defaultEditors.put(char[].class, new CharArrayPropertyEditor());

	// The JDK does not contain a default editor for char!
	this.defaultEditors.put(char.class, new CharacterEditor(false));
	this.defaultEditors.put(Character.class, new CharacterEditor(true));

	// Spring's CustomBooleanEditor accepts more flag values than the JDK's default editor.
	this.defaultEditors.put(boolean.class, new CustomBooleanEditor(false));
	this.defaultEditors.put(Boolean.class, new CustomBooleanEditor(true));

	// The JDK does not contain default editors for number wrapper types!
	// Override JDK primitive number editors with our own CustomNumberEditor.
	this.defaultEditors.put(byte.class, new CustomNumberEditor(Byte.class, false));
	this.defaultEditors.put(Byte.class, new CustomNumberEditor(Byte.class, true));
	this.defaultEditors.put(short.class, new CustomNumberEditor(Short.class, false));
	this.defaultEditors.put(Short.class, new CustomNumberEditor(Short.class, true));
	this.defaultEditors.put(int.class, new CustomNumberEditor(Integer.class, false));
	this.defaultEditors.put(Integer.class, new CustomNumberEditor(Integer.class, true));
	this.defaultEditors.put(long.class, new CustomNumberEditor(Long.class, false));
	this.defaultEditors.put(Long.class, new CustomNumberEditor(Long.class, true));
	this.defaultEditors.put(float.class, new CustomNumberEditor(Float.class, false));
	this.defaultEditors.put(Float.class, new CustomNumberEditor(Float.class, true));
	this.defaultEditors.put(double.class, new CustomNumberEditor(Double.class, false));
	this.defaultEditors.put(Double.class, new CustomNumberEditor(Double.class, true));
	this.defaultEditors.put(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, true));
	this.defaultEditors.put(BigInteger.class, new CustomNumberEditor(BigInteger.class, true));

	// Only register config value editors if explicitly requested.
	if (this.configValueEditorsActive) {
		StringArrayPropertyEditor sae = new StringArrayPropertyEditor();
		this.defaultEditors.put(String[].class, sae);
		this.defaultEditors.put(short[].class, sae);
		this.defaultEditors.put(int[].class, sae);
		this.defaultEditors.put(long[].class, sae);
	}
}

(3)后置处理器ApplicationContextAwareProcessor

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));此行代码主要是添加后置处理器,其实现类ApplicationContextAwareProcessor为BeanPostProcessor接口的子类,对于BeanPostProcessor主要是定义了postProcessBeforeInitialization(初始化前)和postProcessAfterInitialization(初始化后)的方法,ApplicationContextAwareProcessor后置处理器只重写了初始化前方法postProcessBeforeInitialization,其主要作用是设置在后面初始化bean时可以获得一些重要资源如invokeAwareInterfaces中的设置,代码如下:

 @Override
 @Nullable
 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
     if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
             bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
             bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
         return bean;
     }
     AccessControlContext acc = null;
     if (System.getSecurityManager() != null) {
         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 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);
     }
 }

(4)忽略依赖

在上一步增加后置处理器ApplicationContextAwareProcessor——>invokeAwareInterfaces中可以看到如果一些特殊bean是某些XXXAware的子类时,已经不是一个简单的Bean,spring在自动装配即依赖注入时会自动忽略EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware和ApplicationContextAware,会通过其他方式单独处理。

beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

(5)注册依赖

设置了忽略依赖后,spring也设计了注册依赖,若bean依赖了BeanFactory、ResourceLoader、ApplicationEventPublisher和ApplicationContext接口时会自动注入

beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
例如:这几个属性都会被自动设置,虽然没有在显示的在bean定义xml中会被注入
private BeanFactory beanFactory;
private ResourceLoader resourceLoader;
private ApplicationEventPublisher appEventPublisher;
private ApplicationContext appContext;

(6)增加事件监听器ApplicationListenerDetector

ApplicationListenerDetector事件监听器也是后置处理器的一种,只是spring在检查的bean的时候,如果在初始化完成时发现是监听器时会被调用,后面分析bean的初始化时会详细分析;

(7)增加后置处理器LoadTimeWeaverAwareProcessor

判断容器是否存在loadTimeWeaver这种bean的名称时,若存在,则增加LoadTimeWeaverAwareProcessor后置处理器;

(8)注册系统信息

注册系统配置(systemProperties)和系统环境(systemEnvironment、environment)信息。

4、容器扩展——postProcessBeanFactory(beanFactory)

spring5.0.X版本是默认为空实现,由子类容器去实现,是属于spring开放性设计的一种,最大程度满足自身业务需求。

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {

}

5、激活BeanFactory处理器——invokeBeanFactoryPostProcessors(beanFactory)

invokeBeanFactoryPostProcessors方法的主要作用是激活BeanFactory后置处理器,分为硬编码和配置文件添加进来的后置处理器两种处理,硬编码注入的后置处理器如自定义子类实现了容器时调用AbstractApplicationContext——>addBeanFactoryPostProcessor方法,会将其保存在beanFactoryPostProcessors变量中,invokeBeanFactoryPostProcessors中的getBeanFactoryPostProcessors()方法可以获取该值。用于传递给PostProcessorRegistrationDelegate——>invokeBeanFactoryPostProcessors中去处理。

硬编码的后置处理器逻辑如下:

(1)容器是否实现BeanDefinitionRegistry接口,若未实现,直接调用后置处理器BeanFactoryPostProcessor中的方法;
(2)若容器实现BeanDefinitionRegistry,则分两种处理逻辑,一种为BeanDefinitionRegistryPostProcessor,则激活postProcessBeanDefinitionRegistry方法;另一种则是普通的BeanFactoryPostProcessor,这种是激活postProcessBeanFactory方法,激活时会根据实现PriorityOrdered接口、Ordered接口、无两种实现接口顺序激活;配置文件中的后置会理器逻辑其实也是和硬编码一致,不一样的是注入进来时是在解析的时候,放置在beanFactory中,直接可以从容器中获取,然后遍历处理,逻辑大体一致。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  /**
   * 传入Bean工厂并获取BeanFactory后置处理器
   * 此时传入的beanFactory后置处理器还未被初始化
   * 主要是激活BeanFactory后置处理器,包含BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor类型
   * 其中还有对硬编码、配置文件等的beanFactory后置处理器的激活,激活时会伴随着优先级、排序、其他的一些分类处理逻辑。
   */
     PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

     //容器中是否包含LOAD_TIME_WEAVER_BEAN_NAME类型的bean,存在则添加后置处理器
     if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
         beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
         beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
     }
 }

该方法主要是用于处理激活BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor类型的后置处理器,调用其中的postProcessBeanFactory和 postProcessBeanDefinitionRegistry方法,先处理硬编码方式的后置处理器、再处理配置文件中配置的后置处理器。处理过程中会有根据处理器实现的接口进行分类处理如PriorityOrdered、Ordered和无实现两者接口的,代码如下:

 public static void invokeBeanFactoryPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
	//定义个局部变量用于控制下面分类处理时,防止重复激活后置处理器
	Set<String> processedBeans = new HashSet<>();

	//处理实现了BeanDefinitionRegistry的beanFactory容器
	if (beanFactory instanceof BeanDefinitionRegistry) {
	    //强制转化为BeanDefinitionRegistry
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		//用于存储普通的BeanFactory后置处理器
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		//用于存储BeanDefinitionRegistryPostProcessor类型的后置处理器
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
		//遍历处理beanFactory容器中的beanFactoryPostProcessors后置处理器
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
		    //判断bean工厂的后置处理器是否为BeanDefinitionRegistryPostProcessor
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
			    //将其强制转换为BeanDefinitionRegistryPostProcessor类型
				BeanDefinitionRegistryPostProcessor registryProcessor =	(BeanDefinitionRegistryPostProcessor) postProcessor;
				//调用该后置处理器中的postProcessBeanDefinitionRegistry方法
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);//将该后置处理器存入registryProcessors集合中
			}else {
				regularPostProcessors.add(postProcessor);//将普通的beanFactoryPostProcessor存入regularPostProcessors集合中
			}
		}

		//定义一个集合用于存储当前准备创建的BeanDefinitionRegistryPostProcessor
		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

		/**
		 * 第一步:
		 * 从容器中先获取BeanDefinitionRegistryPostProcessor类型的bean名称即该类型的处理器名称
		 */
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		//遍历BeanDefinitionRegistryPostProcessor这种类型的所有处理器名称,处理实现了PriorityOrdered接口的后置处理器
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//处理器是否实现了PriorityOrdered接口
			    //使用getBean方法从容器中获得bean对象即BeanDefinitionRegistryPostProcessor类型的对象,存入currentRegistryProcessors中
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);//将该处理器的名称存入processedBeans集合中,该方法第一行定义的set集合
			}
		}
		//对currentRegistryProcessors集合进行排序
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		从容器中获取的BeanDefinitionRegistryPostProcessor存入registryProcessors集合中
		registryProcessors.addAll(currentRegistryProcessors);
		//激活处理器中的postProcessBeanDefinitionRegistry方法即处理器中实现的方法
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		currentRegistryProcessors.clear();//立即清空该集合,后面再次利用

		/**
		 * 第二步:
		 * 与上面处理实现了PriorityOrdered接口的后置处理器一样
		 * 此处是处理实现了Ordered接口的后置处理器
		 */
		postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		registryProcessors.addAll(currentRegistryProcessors);
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		currentRegistryProcessors.clear();

		/**
		 * 第三步:
		 * 处理beanFactory中既没有实现PriorityOrdered优先级接口
		 * 也没有实现Ordered接口的BeanDefinitionRegistryPostProcessor类型的后置处理器
		 */
		boolean reiterate = true;
		while (reiterate) {
			reiterate = false;
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
					reiterate = true;
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();
		}

		/**
		 * 第四步:
		 * 调用实现了BeanDefinitionRegistryPostProcessor接口的后置处理器,BeanDefinitionRegistryPostProcessor接口
		 * 也继承了BeanFactoryPostProcessor接口,此处的调用实际上是调用BeanFactoryPostProcessor中的postProcessBeanFactory方法
		 */
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		/**
            * 第五步:
            * 调用实现了BeanFactoryPostProcessor接口,未实现BeanDefinitionRegistryPostProcessor接口的后置处理器
            * 中的postProcessBeanFactory方法
            */
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	}else {
		//beanFactory容器未实现BeanDefinitionRegistry接口时,需要激活的后置处理器中的postProcessBeanFactory方法
		invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
	}

	//获取容器中所有BeanFactoryPostProcessor类型的后置处理器,上述的那些处理器是getBeanFactoryPostProcessors()获取的
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

	//遍历postProcessorNames数组,根据PriorityOrdered优先级接口、Ordered接口和无两者的实现进行分类存储
	List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	List<String> orderedPostProcessorNames = new ArrayList<>();
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
		if (processedBeans.contains(ppName)) {
			//已存在就跳过
		}
		else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
		    //创建并存储创建的后置处理器
			priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		}
		else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	//激活实现优先级接口的处理器
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

	//创建和激活实现排序接口的处理器
	List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	for (String postProcessorName : orderedPostProcessorNames) {
		orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

	//与上述一样,处理既没有实现PriorityOrdered接口的、也没有实现Ordered接口的后置处理器
	List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	for (String postProcessorName : nonOrderedPostProcessorNames) {
		nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

	//清除缓存
	beanFactory.clearMetadataCache();
}

6、注册registerBeanPostProcessors(beanFactory)

 public static void registerBeanPostProcessors(
           ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
       //获取容器中的所有BeanPostProcessor类型的后置处理器
       String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

       //计算后置处理器的个数,+1是代表注册的BeanPostProcessorChecker
       int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
       //增加一个后置处理器BeanPostProcessorChecker,用于输出spring后置处理器还未被注册时bean已经开始初始化时会打印内置日志
       beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

       List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();//定义优先级后置处理器集合
       List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();//MergedBeanDefinitionPostProcessor类型的集合
       List<String> orderedPostProcessorNames = new ArrayList<>();//排序后的后置处理器名称集合
       List<String> nonOrderedPostProcessorNames = new ArrayList<>();//无序的后置处理器名称集合
       //遍历后置处理器名称数组,进行创建BeanPostProcessor对象并归类存储,此处只对实现了PriorityOrdered接口的后置处理器进行对象创建
       //在其创建的对象中发现是MergedBeanDefinitionPostProcessor接口类型的,也对其进行归类存储
       for (String ppName : postProcessorNames) {
           if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
               BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
               priorityOrderedPostProcessors.add(pp);
               if (pp instanceof MergedBeanDefinitionPostProcessor) {
                   internalPostProcessors.add(pp);
               }
           }else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
               orderedPostProcessorNames.add(ppName);
           }else {
               nonOrderedPostProcessorNames.add(ppName);
           }
       }

       //第一步:先对实现了PriorityOrdered接口的后置处理器进行排序和注册
       sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
       registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

       //对实现了Ordered接口的后置处理器创建BeanPostProcessor对象,并对其有MergedBeanDefinitionPostProcessor的进行归类存储
       List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
       for (String ppName : orderedPostProcessorNames) {
           BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
           orderedPostProcessors.add(pp);
           if (pp instanceof MergedBeanDefinitionPostProcessor) {
               internalPostProcessors.add(pp);
           }
       }
       //第二步:然后对实现了Ordered接口的后置处理器进行排序和注册
       sortPostProcessors(orderedPostProcessors, beanFactory);
       registerBeanPostProcessors(beanFactory, orderedPostProcessors);

       // Now, register all regular BeanPostProcessors.
       List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
       for (String ppName : nonOrderedPostProcessorNames) {
           BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
           nonOrderedPostProcessors.add(pp);
           if (pp instanceof MergedBeanDefinitionPostProcessor) {
               internalPostProcessors.add(pp);
           }
       }
       registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

       // Finally, re-register all internal BeanPostProcessors.
       sortPostProcessors(internalPostProcessors, beanFactory);
       registerBeanPostProcessors(beanFactory, internalPostProcessors);

       // Re-register post-processor for detecting inner beans as ApplicationListeners,
       // moving it to the end of the processor chain (for picking up proxies etc).
       beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
   }

7、初始化不同语言消息体——initMessageSource()

容器支持用户自定义配置消息体,将其注入到spring容器中,在其中beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)中使用硬编码方式命名bean名称即Id必须为messageSource,否则无法识别为消息体。

protected void initMessageSource() {
       ConfigurableListableBeanFactory beanFactory = getBeanFactory();//获取容器
       if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {//判断是否有配置自定义的messageSource
           this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
           if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
               HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
               if (hms.getParentMessageSource() == null) {
                   hms.setParentMessageSource(getInternalParentMessageSource());
               }
           }
           if (logger.isTraceEnabled()) {
               logger.trace("Using MessageSource [" + this.messageSource + "]");
           }
       }else {//未自定义消息体,则使用默认DelegatingMessageSource来初始化,便于返回getMessage
           DelegatingMessageSource dms = new DelegatingMessageSource();
           dms.setParentMessageSource(getInternalParentMessageSource());
           this.messageSource = dms;
           beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
           if (logger.isTraceEnabled()) {
               logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
           }
       }
   }

8、初始化上下文消息广播——initApplicationEventMulticaster()

事件广播器分为自定义事件广播器(bean的id必须为applicationEventMulticaster)和默认的事件广播器SimpleApplicationEventMulticaster来作为事件广播器。

  protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //是否有自定义的事件广播器applicationEventMulticaster
        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
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
            if (logger.isTraceEnabled()) {
                logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
                        "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
            }
        }
    }

自定义事件广播器如下:
(1)先定义事件即执行业务:必须要初始化父类中的变量source

 public class TestEvent extends ApplicationEvent {
        public 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)定义监听器:必须实现ApplicationListener接口中的方法onApplicationEvent作为执行事件

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

(3)添加到配置文件:在XML配置文件中配置

<bean id = "testListener" class="com.spring.test.TestListener" />

(4)测试用例

 public static void main(String[] args) {
      ApplicationContext applicationContext = new ClassPathXmlApplicationContext("config/applicationContext.xml");
      TestEvent testEvent = new TestEvent("hello","MSG");//初始化资源source
      applicationContext.publishEvent(testEvent);//发布事件到容器
  }

9、容器自定义刷新——onRefresh()

onRefresh()方法是自定义子类容器时,通过重写该方法,执行用户自身的额外逻辑而添加,也是spring开放性设计的体现,spring自身默认为空。

protected void onRefresh() throws BeansException {
    // For subclasses: do nothing by default.
}

10、注册监听器——registerListeners()

registerListeners()方法处理硬编码方式和XMl配置文件注册的监听器,将其添加到变量applicationEventMulticaster中,最后将事件应用到事件管理器applicationEventMulticaster中,用户通过发布publishEvent方法通知事件管理器中的监听器onApplicationEvent方法。

说明:事件、事件发布者、事件管理器和事件监听器组成了一个完整的发布——订阅的完整链路,event用户定义,用户进行发布,spring容器在此步将其注册到applicationEventMulticaster中,事件管理器中的监听器会接受到事件,其中onApplicationEvent方法执行就是监听器中回应。

protected void registerListeners() {
      //处理硬编码方式注册到spring容器中,将beanFactory中解析的注册器添加到applicationEventMulticaster中
      for (ApplicationListener<?> listener : getApplicationListeners()) {
          getApplicationEventMulticaster().addApplicationListener(listener);
      }

      /**
       * 处理XML配置文件中ApplicationListener类型的bean监听器,将其添加到applicationEventMulticaster中
       * 此处只是获取了bean的名称,并未初始化监听器
       */
      String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
      for (String listenerBeanName : listenerBeanNames) {
          getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
      }

      //将事件Event应用到onApplicationEvent方法中
      Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
      this.earlyApplicationEvents = null;
      if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
          for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
              getApplicationEventMulticaster().multicastEvent(earlyEvent);
          }
      }
  }

11、初始化非延迟加载单例——finishBeanFactoryInitialization(beanFactory)

初始化bean常规饿汉式单实例bean即非惰性的bean,经典的getBean方法被调用,代码执行到此处,BeanFactory已经创建完成,并且所有的实现了BeanFactoryPostProcessor接口的Bean都已经初始化并且其中的postProcessBeanFactory(factory)方法已经得到回调执行了。而且Spring已经“手动”注册了一些特殊的Bean,如environment、systemProperties、监听器等等。剩下的就是初始化所有的单例bean,大多数我们的业务中都是单例bean,就像我们写的@Controller、@Service的类(没有设置懒加载的)都是在这个地方初始化,以供我们使用,如果没有设置懒加载,那么Spring会在接下来初始化所有的singleton beans。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    /**
     * 容器中有配置bean名称为conversionService时,则使用getBean对其进行初始化
     * conversionService类 它用来将前端传过来的参数和后端的 controller 方法上的参数进行绑定的时候用
     */
    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));
    }

    // Register a default embedded value resolver if no bean post-processor
    // (such as a PropertyPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    //获取LoadTimeWeaverAware类型的,主要是Aop的实现原理
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    //清空临时类加载器
    beanFactory.setTempClassLoader(null);

    //暂停临时的类加载器使用
    beanFactory.freezeConfiguration();

    //委托给DefaultListableBeanFactory去实例化非懒加载的单例bean(核心)
    beanFactory.preInstantiateSingletons();
}

DefaultListableBeanFactory负责去实例化单例bean,

@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) {
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		//非抽象、非懒加载的singletons。如果配置了abstract=true是不需要初始化的
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
		    //处理factoryBean类型的bean
			if (isFactoryBean(beanName)) {
				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
				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);
					}
				}

			}else {//处理spring容器中的普通bean,即常用的controller、service等注解的bean
				getBean(beanName);//bean初始化
			}
		}
	}

	//触发容器中bean实现了SmartInitializingSingleton接口的回调方法
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			}else {
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}

12、刷新完成通知器——finishRefresh():

通知生命周期处理器LifecycleProcessor刷新且发出ContextRefreshEvent通知

protected void finishRefresh() {
    //清理容器级别的缓存
    clearResourceCaches();

    //初始化上下文的生命周期处理器即初始化LifecycleProcessor
    initLifecycleProcessor();

    //刷新所有实现了Lifecycle接口的Bean中的onRefresh()方法
    getLifecycleProcessor().onRefresh();

    //发布ContextRefreshEvent事件告知容器已完成刷新
    publishEvent(new ContextRefreshedEvent(this));

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

ApplicationContext在启动或停止时, 通过LifecycleProcessor来与所有声明的Bean的周期做状态更新.Spring会先从容器中获取BeanName为lifecycleProcessor的Bean实例,如果没有则使用Spring默认的DefaultLifecycleProcessor。如果是自定义LifecycleProcessor则需要将自己定义的LifecycleProcessor声明bean的id为lifecycleProcessor。

protected void initLifecycleProcessor() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
        this.lifecycleProcessor =
                beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
        if (logger.isTraceEnabled()) {
            logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
        }
    }else {
        DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
        defaultProcessor.setBeanFactory(beanFactory);
        this.lifecycleProcessor = defaultProcessor;
        beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
        if (logger.isTraceEnabled()) {
            logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
                    "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
        }
    }
}

getLifecycleProcessor().onRefresh()刷新所有实现了Lifecycle接口的Bean,将LifecycleProcessor初始化完成之后,调用LifecycleProcessor接口的onRefresh()方法刷新所有实现了Lifecycle的Bean。

DefaultLifecycleProcessor——>startBeans()代码如下:

 private void startBeans(boolean autoStartupOnly) {
        Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
        Map<Integer, LifecycleGroup> phases = new HashMap<>();
        lifecycleBeans.forEach((beanName, bean) -> {
            if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
                int phase = getPhase(bean);
                LifecycleGroup group = phases.get(phase);
                if (group == null) {
                    group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                    phases.put(phase, group);
                }
                group.add(beanName, bean);
            }
        });
        if (!phases.isEmpty()) {
            List<Integer> keys = new ArrayList<>(phases.keySet());
            Collections.sort(keys);
            for (Integer key : keys) {
                phases.get(key).start();
            }
        }
    }

publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件,当完成ApplicationContext容器刷新时,Spring通过事件发布机制发布ContextRefreshedEvent事件。
代码如下:

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
   Assert.notNull(event, "Event must not be null");
   //将事件封装为ApplicationEvent
   ApplicationEvent applicationEvent;
   if (event instanceof ApplicationEvent) {
       applicationEvent = (ApplicationEvent) event;
   }else {
       applicationEvent = new PayloadApplicationEvent<>(this, event);
       if (eventType == null) {
           eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
       }
   }

   if (this.earlyApplicationEvents != null) {
       this.earlyApplicationEvents.add(applicationEvent);
   }else {
       getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);//使用事件广播器
   }

   if (this.parent != null) {
       if (this.parent instanceof AbstractApplicationContext) {
           ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
       }else {
           this.parent.publishEvent(event);
       }
   }
}

(五)总结

ApplicationContext容器中的refresh()中十二核心执行步骤:

(1)prepareRefresh():初始化前的准备工作,如需要使用系统变量或环境变量中的路径或值作为spring中使用值,那么再其启动前就有验证的必要性;
(2)obtainFreshBeanFactory():初始化BeanFactory并进行XML配置文件读取,ApplicationContext拥有BeanFactory的一切基于此;
(3)prepareBeanFactory(beanFactory):对BeanFactory进行功能填充;
(4)postProcessBeanFactory(beanFactory):子类通过覆盖该方法进行自定义扩展,默认为空实现即扩展性强原因于此;
(5)invokeBeanFactoryPostProcessors(beanFactory):激活各种BeanFactory处理器;
(6)registerBeanPostProcessors(beanFactory):将拦截到的Bean创建的Bean处理器注册,仅注册;
(7)initMessageSource():为上下文初始化不同语言消息体,国际化处理;
(8)initApplicationEventMulticaster():初始化上下文消息广播,即监听器处理;
(9)onRefresh();子类重写时自定义扩展,默认为空;
(10)registerListeners():在注册的bean中将监听器注册到消息广播器中;
(11)finishBeanFactoryInitialization(beanFactory):初始化bean常规饿汉式单实例bean即非惰性的bean,经典的getBean方法被调用;
(12)finishRefresh():刷新完成通知器,通知生命周期处理器LifecycleProcessor刷新且发出ContextRefreshEvent通知。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
`refresh()` 是 Spring 框架中的一个方法,它用于刷新应用程序上下文(ApplicationContext)以更新其内部状态。在 Spring 框架中,`refresh()` 方法是非常重要的,因为它负责完成应用程序上下文的初始化和配置,并准备好所有的单例 bean 以供使用。 下面是 `refresh()` 方法的主要流程: 1. 准备刷新过程中需要用到的变量和标志位; 2. 调用 `prepareRefresh()` 方法,进行一些预处理工作; 3. 调用 `obtainFreshBeanFactory()` 方法,创建 BeanFactory 并进行一些初始化工作; 4. 调用 `prepareBeanFactory(beanFactory)` 方法,对 BeanFactory 进行一些后续处理; 5. 调用 `postProcessBeanFactory(beanFactory)` 方法,对 BeanFactory 进行后置处理; 6. 调用 `invokeBeanFactoryPostProcessors(beanFactory)` 方法,执行 BeanFactoryPostProcessor 的 postProcessBeanFactory() 方法; 7. 调用 `registerBeanPostProcessors(beanFactory)` 方法,注册 BeanPostProcessor 实例; 8. 调用 `initMessageSource()` 方法,初始化 MessageSource 组件; 9. 调用 `initApplicationEventMulticaster()` 方法,初始化 ApplicationEventMulticaster 组件; 10. 调用 `onRefresh()` 方法,进行一些自定义的刷新工作; 11. 调用 `registerListeners()` 方法,注册事件监听器; 12. 调用 `finishBeanFactoryInitialization(beanFactory)` 方法,完成所有非延迟初始化的单例 bean 的初始化工作; 13. 调用 `finishRefresh()` 方法,完成上下文的刷新工作。 需要注意的是,`refresh()` 方法在执行过程中会涉及到很多细节,比如如何处理环境变量、如何处理自定义的 bean 定义、如何处理多个上下文之间的关系等等。如果需要深入了解 `refresh()` 方法的实现细节,可以查看 Spring 框架的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值