前言:spring系列第二篇文章,前面懒病犯了。(笑)
本篇主要讲解context.refresh()方法
0. 准备工作
Test.Java
public class Test {
public static void main(String[] args) throws IOException {
// 把spring所有的前提环境准备好(比如:bean容器、bean工厂等)
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext();
// 像容器注入配置类,后面来讲。
context.register(AppConfig.class);
// 本篇主要讲解的内容
context.refresh();
AppConfig bean = context.getBean(AppConfig.class);
System.out.println(bean);
}
}
1. 源码阅读
Refresh()方法
方法处于AbstractApplicationContext类,方法里面做了很多的事情,首先我们点开这个方法:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 准备工作包括:设置启动时间、是否激活标识位、初始化属性源(property source)配置
// 和主流程关系不太大
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 得到beanFactory,然后对beanFactory进行设置
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 重点方法,准备beanFactory
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 空方法,当前版本没有代码
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
/*
* 在spring的环境中执行已经被注册的 factory processors
* 设置执行自定义和spring内部的beanFactoryPostProcessor
* 这里执行了了spring内部最关键的一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
*/
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册bean的处理器来拦截bean的创建
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 这个方法不太重要。国际化
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 空壳方法
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化所有剩余的不是懒加载的单例bean,又一个重点方法。
// 何谓剩余?单例bean有两种:spring内置的、自己添加的(这就是代表剩余的)
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 最后一步:发布相应的事件
finishRefresh();
// ... 省略后面的
}
}
里面有很多调用的方法,我们先一个一个的分析:
1.1 prepareRefresh()
正如其命名一样,该方法做的工作主要是:设置启动时间、是否激活标识位、初始化属性源(property source)配置等,与主流程关系不大。有兴趣的可以自己专研下。
1.2 obtainFreshBeanFactory()
取出得到beanFactory,然后对beanFactory进行设置。关于什么是beanFactory,简单来说就是一个工厂,里面有储存着所有要用的东西,等后面再来详细说明。
1.3 prepareBeanFactory()
// Prepare the bean factory for use in this context.
// 重点方法,准备beanFactory
prepareBeanFactory(beanFactory);
这是一个比较重要的方法,里面完成了很多工作:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 设置一个类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// bean的表达式解析,能够获取bean当中的属性,在前台页面
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 对象与字符串之间的转换
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks. 配置工厂的回调
// 增加一个后置管理器。 ApplicationContextAwareProcessor 实现了BeanPostProcessor
// ApplicationContextAwareProcessor 这个类也会在后面介绍的
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //最核心的
// 以下接口,忽略自动装配
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
// ...省略部分
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 依赖的替换
//以下接口,允许自动装配,第一个参数是自动装配的类型,,第二个字段是自动装配的值
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
// ...省略部分
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
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中没有名为"systemProperties"和"systemEnvironment"的Bean.
* 则注册两个Bean,Key为"systemProperties"和"systemEnvironment",Value为Map,
* 这两个Bean就是一些系统配置和系统环境信息
*/
// Register default environment beans. 注册默认的环境bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
// ...省略部分
}
主要做了如下工作:
- 设置一个类加载器
- bean的表达式解析,能够获取bean当中的属性,在前台页面
- 设置对象与字符串之间的转换的类
- 添加了一个后置处理器:
ApplicationContextAwareProcessor
,其实现了接口BeanPostProcessor
(其作为spring扩展点之一,这个接口会在后面详细讲解的) - 设置忽略自动装配的接口
- 相关依赖的替换
- 设置一些系统配置和系统环境信息
1.4 postProcessBeanFactory()
// 空方法,当前版本没有代码
postProcessBeanFactory(beanFactory);
这个方法是在标准初始化完成后,用于修改内部beanFactory的方法,当前版本没有实现,可能在后续的版本中增加相关的实现。
1.5 invokeBeanFactoryPostProcessors()
// Invoke factory processors registered as beans in the context.
/*
* 在spring的环境中执行已经被注册的 factory processors
* 设置执行自定义和spring内部的beanFactoryPostProcessor
* 这里执行了了spring内部最关键的一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
*/
invokeBeanFactoryPostProcessors(beanFactory);
这个方法是非常重要的一个方法,完成了非常重要的工作,这篇就讲个开始, 下一篇将重点讲解此方法里面内容。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// getBeanFactoryPostProcessors()方法是获取手动(这个是没有交给spring容器管理的,也就是没加@Component)
/**
* getBeanFactoryPostProcessors()返回的是AnnotationConfigApplicationContext继承的父类中被定义的
* 一个List,是一个空的。
* 是需要自己调用AnnotationConfigApplicationContext的addBeanFactoryPostProcessors()方法添加进去
*/
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// ...省略部分内容
}
}
1.5.1 getBeanFactoryPostProcessors()
先看这个方法:
getBeanFactoryPostProcessors()返回的是AnnotationConfigApplicationContext继承的父类中被定义的一个List,是一个空的。
是需要自己调用AnnotationConfigApplicationContext的addBeanFactoryPostProcessors()方法添加进去。
addBeanFactoryPostProcessor()方法
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
// ....
this.beanFactoryPostProcessors.add(postProcessor);
}
当没有手动调用add方法时,从截图可以清楚看到里面并没有内容
当我们在Test类中的main方法中调用addBeanFactoryPostProcessor()方法时:
可以从下图看出结果:
本篇文章到这就完结,后面的内容,下篇文章再写。希望我能更新更快一点(逃