Spring启动和Bean创建过程中的可扩展接口

Spring中有一些可以扩展的接口,可以用来在工作中更深度的使用Spring,这些接口大多分布在AbstractApplicationContext.refresh() 和 AbstractAutowireCapableBeanFactory.createBean()这两个方法的执行过程中。

2.AbstractApplicationContext.refresh()

2.1 refresh()简介

AbstractApplicationContext.refresh()是Spring环境启动 过程中的一个重要方法,此方法中实例化了所有的bean任何ApplicationContext的实现,都需要调用此方法

Spring启动和Bean创建过程中的可扩展接口

如上图所示,Spring中,所有的ApplicationContext,都继承于AbstractApplicationContext。

为节省篇幅,仅将要分析的几个方法代码片段抽取出来,refresh()的全部实现可查看源码中的AbstractApplicationContext.refresh()方法。

// Prepare this context for refreshing.
prepareRefresh();

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

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);

// Initialize event multicaster for this context.
initApplicationEventMulticaster();

// Check for listener beans and register them.
registerListeners();
复制代码

2.2 prepareRefresh()

调用了initPropertySources,初始化资源,如属性文件中的占位符等。 由子类实现,如AbstractRefreshableWebApplicationContext。

2.3 obtainFreshBeanFactory()

获取ConfigurableListableBeanFactory:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	refreshBeanFactory();
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (logger.isDebugEnabled()) {
		logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
	}
	return beanFactory;
}
复制代码

此方法中主要执行两部分流程:

2.3.1 调用refreshBeanFactory()

调用抽象方法refreshBeanFactory(),由子类AbstractRefreshableApplicationContext实现,代码片段如下:

DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);  //读取xml,注册BeanDefinition。
复制代码

loadBeanDefinitions是AbstractRefreshableApplicationContext的一个抽象方法,由其子类AbstractXmlApplicationContext实现 ,详细了解AbstractXmlApplicationContext可参考 Spring自定义配置的源码解析与实现

2.3.2 调用getBeanFactory()

调用抽象方法getBeanFactory(),由子类AbstractRefreshableApplicationContext实现,返回一个接口ConfigurableListableBeanFactory的实现类DefaultListableBeanFactory的实例。

这个DefaultListableBeanFactory实例,由上面的refreshBeanFactory()中调用createBeanFactory()创建。

2.4 prepareBeanFactory

配置ConfigurableListableBeanFactory。

ConfigurableListableBeanFactory继承了BeanFactory,实现类是DefaultListableBeanFactory。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory){....}

2.4.1 设置classLoader:

beanFactory.setBeanClassLoader(getClassLoader());

通过org.springframework.util.ClassUtils.getDefaultClassLoader()获取ClassLoader。

2.4.2 创建ApplicationContextAwareProcessor

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

创建ApplicationContextAwareProcessor对象,并且添加到DefaultListableBeanFactory中。

ApplicationContextAwareProcessor实现了BeanPostProcessor,并在实现的BeanPostProcessor.postProcessBeforeInitialization中,定义了对一些列对org.springframework.beans.factory.Aware子接口的处理。

注:这里只是添加了BeanPostProcessor,但并未执行。

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);
		}
	}
}
复制代码

在后续创建Bean的流程中,会执行所有的BeanPostProcessor,也就是会执行ApplicationContextAwareProcessor.postProcessBeforeInitialization设置各种Aware接口。

2.4.3 设置默认的上下文bean

注册Spring自身使用的一些Bean:

// Register default environment beans.
		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());
		}
复制代码

其中:

String ENVIRONMENT_BEAN_NAME = "environment";
String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
复制代码

2.5 invokeBeanFactoryPostProcessors

调用所有的 BeanFactoryPostProcessor.postProcessBeanFactory。 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors){....}
复制代码

2.6 registerBeanPostProcessors

注册所有的BeanPostProcessor

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}
复制代码

2.7 initApplicationEventMulticaster

初始化ApplicationEventMulticaster,实现类是SimpleApplicationEventMulticaster。

this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
复制代码

public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";

2.8 registerListeners

向ApplicationEventMulticaster注册ApplicationListner。

/**
	 * Add beans that implement ApplicationListener as listeners.
	 * Doesn't affect other listeners, which can be added without being beans.
	 */
	protected void registerListeners() {
		// Register statically specified listeners first.
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}
复制代码

3 AbstractAutowireCapableBeanFactory.createBean()

3.1 DefaultListableBeanFactory

Spring启动和Bean创建过程中的可扩展接口

如上图所示,
DefaultListableBeanFactory

是ListableBeanFactory和BeanDefinitionRegistry的默认实现,是所有BeanFactory的始祖。最终创建bean的,是它的直接父类AbstractAutowireCapableBeanFactory.createBean 。

3.2 createBean

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {....}

主要执行了两个方法:

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
Object beanInstance = doCreateBean(beanName, mbdToUse, args);

3.3 AbstractAutowireCapableBeanFactory.doCreateBean

3.3.1 createBeanInstance

BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) 主要做了以下工作:

Class<?> beanClass = resolveBeanClass(mbd, beanName);
BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd)
getInstantiationStrategy().instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner)

3.3.2 populateBean

populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) 根据BeanDefinition为BeanWrapper封装的bean代理对象设置属性值。设置的方式,是创建了BeanDefinitionValueResolver对象,并BeanDefinitionValueResolver.resolveValueIfNecessary实现。resolveValueIfNecessary执行了一系列判断和递归调用,将属性值填充。

3.3.3 initializeBean

Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd)

  • 1 invokeAwareMethods : 执行 BeanNameAware , BeanClassLoaderAware , BeanFactoryAware

  • 2 applyBeanPostProcessorsBeforeInitialization: 调用了所有 BeanPostProcessor的postProcessBeforeInitialization 方法。

  • 3 invokeInitMethods:

    • 1)执行 InitializingBean.afterPropertiesSet
    • 2)执行 init-method;
  • 4 applyBeanPostProcessorsAfterInitialization: 执行所有的 BeanPostProcessor 的 postProcessAfterInitialization 方法。

3.3.4 registerDisposableBeanIfNecessary

注册Bean销毁事件。 protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd)

  • 1 执行 DisposableBean.destroy() ;
  • 2 执行destroy-method;

4 总结

4.1 **Aware

实现**Aware类的接口,用于获取到Spring环境中的各种信息或对象:

常用的有:

  • ApplicationContextAware:获取当前的ApplicationContext;
  • BeanNameAware:获取当前的beanName;
  • BeanClassLoaderAware:获取当前的ClassLoader;
  • BeanFactoryAware:获取当前的BeanFactory;
  • ApplicationEventPublisherAware:获取当前的ApplicationEventPublisher,用于发布事件;要接收事件的类可以实现ApplicationListener接口,并实现其中的onApplicationEvent方法。

其他还有:

  • EnvironmentAware
  • EmbeddedValueResolverAware
  • ResourceLoaderAware
  • MessageSourceAware

用于其他各种Spring上下文信息的获取。

使用:Bean类实现**Aware接口。

4.2 BeanFactoryPostProcessor

容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改。

BeanFactoryPostProcessor只定义了一个方法: postProcessBeanFactory(ConfigurableListableBeanFactory)

在所有bean的定义已经加载,但是还没有初始化bean的时候,Spring容器会调用此方法,并可以根据需要修改ConfigurableListableBeanFactory的内容,如如PropertySourcesPlaceholderConfigurer。

使用:Bean类实现BeanFactoryPostProcessor接口,或调用AbstractApplicationContext.addBeanFactoryPostProcessor添加。

4.3 ApplicationListener

接收ApplicationEventMulticaster广播的事件,事件是ApplicationEvent及其子类。

接收的是 ApplicationEventPublisher 发布的事件。

使用:Bean类实现ApplicationListener接口并实现其定义的方法onApplicationEvent(E event),或调用AbstractApplicaitonContext.addApplicationListener添加。

4.4 BeanPostProcessor

有两个方法,分别在InitializingBean前后执行,对bean对象进行处理。

  • postProcessBeforeInitialization :在InitializingBean和init-method前执行;
  • postProcessAfterInitialization:在InitializingBean和init-method后执行;

注:不能返回null,否则程序将不再往下进行。如不需要处理则返回原对象即可。

使用:Bean类实现BeanPostProcessor接口,或调用AbstractBeanFactory. addBeanPostProcessor添加。

原文 

https://juejin.im/post/5dd8a6a1e51d4522fe5ef375

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Spring启动和Bean创建过程中的可扩展接口

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址