三、容器的功能扩展
1.示例代码
ApplicationContext bf = new ClassPathXmlApplicationContext("beanFactoryText.xml");
2.ClassPathXmlApplicationContext
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
3.核心方法refresh()
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//1.准备刷新的上下文环境
prepareRefresh();
//2.初始化BeanFactory,并进行XML文件读取
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3.功能扩展
prepareBeanFactory(beanFactory);
try {
//4.由子类扩展:允许在子类中对beanFactory进行后处理
postProcessBeanFactory(beanFactory);
//5.激活BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
//6.注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);
//7.初始化消息资源
initMessageSource();
//8.初始化事件广播器
initApplicationEventMulticaster();
//9.在子类实现来初始化其他bean
onRefresh();
//10.注册监听器
registerListeners();
//11.实例化所有剩余(非延迟初始化)单例
finishBeanFactoryInitialization(beanFactory);
//12.完成刷新
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
3.1初始化前的准备工作,例如对系统属性或者环境变量进行准备及验证。
/// prepareRefresh方法逻辑 //
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
//子类重写该方法进行个性化的属性处理及设置
initPropertySources();
//对属性进行验证
getEnvironment().validateRequiredProperties();
3.2初始化BeanFactory,并进行xml读取。
ClassPathXmlApplicationContext包含BeanFactory所提供的一切特征,在这一步骤中将会复用BeanFactory中的配置文件读取解析及其他功能。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//指定序列化id
beanFactory.setSerializationId(getId());
//定制beanFactory设置allowBeanDefinitionOverriding和allowCircularReferences
customizeBeanFactory(beanFactory);
//加载BeanDefinition 与第一章中的加载一样
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
//将beanFactory设置到applicationContext
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
3.3功能扩展
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//告诉内部beanFactory使用上下文的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//设置beanFactory的spring表达式语言处理器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//为beanFactory增加一个默认的propertyEditor属性注册编辑器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加一个BeanPostProcessor,对下面的几个Aware类型bean进行注入
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//设置几个忽略自动装配的接口
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);
// 注册早期的后置处理器以检测ApplicationListeners的bean
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 检测LoadTimeWeaver并准备编织(如果找到)
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
//为类型匹配设置临时ClassLoader
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());
}
}
设置忽略依赖知识点
3.4子类实现对beanFactory进行后置处理
///比如子类AbstractRefreshableWebApplicationContext中///
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
3.5激活各种BeanFactory处理器
//在上下文中调用注册为bean的工厂处理器
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 如果在此期间找到,则检测LoadTimeWeaver并准备编织
// 例如通过ConfigurationClassPostProcessor注册的@Bean方法
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
调用BeanFactoryPostProcessor逻辑图
步骤一
步骤二
3.6注册BeanPostProcessor
逻辑和前面激活BeanFactoryPostProcessor相似,从容器中找到所有BeanPostProcessor类型的bean,然后根据PriorityOrdered,Ordered,MergedBeanDefinitionPostProcessor,进行分组并且排序,然后全部注册进beanPostProcessors里。
3.7初始化消息资源
应用:spring国际化
3.8初始化ApplicationEventMulticaster
如果用户自定义了事件广播器,那么使用用户自定义的事件广播器。
如果用户没有自定义事件广播器,那么使用默认的ApplicationEventMulticaster.
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);
}
}
}
当产生Spring事件的时候会默认使用SimpleApplicationEventMulticaster的multicastEvent方法来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent方法来进行监听器的处理。而对于每个监听器来说其实都可以获取到产生的事件,但是是否进行处理则由事件监听器决定。
3.9由子类实现其它特殊bean的初始化
//比如AbstractRefreshableWebApplicationContext实现类中
protected void onRefresh() {
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}
3.10注册监听器
//硬编码方式注册的监听器处理
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
//配置文件注册的监听器处理
//不要在这里初始化FactoryBeans,我们需要保留所有常规bean未初始化,让后处理器应用于它们!
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);
}
}
3.11实例化所有剩余(非延迟初始化)单例
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化此上下文的转换服务(ConversionService)
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
//如果没有bean后处理器(例如PropertyPlaceholderConfigurer bean)在此之前注册任何内容,则注册默认的嵌入值解析器(主要用于注解属性值的解析)。
// 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 bean以允许尽早注册其变换器
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时ClassLoader进行类型匹配
beanFactory.setTempClassLoader(null);
// 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
beanFactory.freezeConfiguration();
// 实例化所有剩余(非延迟初始化)单例。
beanFactory.preInstantiateSingletons();
}
ApplicationContext实现的默认行为就是在启动时将所有单例bean提前进行实例化。提前实例化意味着作为初始化过程的一部分,ApplicationContext实例会创建并配置所有的单例bean。
/DefaultListableBeanFactory类//
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("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)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final 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 {
getBean(beanName);
}
}
}
可以看到方法最终又是调用了第二章中获取实例的方法
3.12完成刷新
完成刷新过程,通知声明周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知对应监听器。