目录
- 前言
- 1、refresh()简介
- 2、关键代码跟踪
- 2.1、obtainFreshBeanFactory()代码分析
- 2.2、invokeBeanFactoryPostProcessors(beanFactory)代码分析
- 2.3、registerBeanPostProcessors(beanFactory)代码分析
- 2.4、registerListeners();代码分析
- 2.5、finishBeanFactoryInitialization(beanFactory)代码分析
- 2.4、finishRefresh()代码分析
- 总结
前言
在《spring初始化源码浅析之关键类和扩展接口》中主要是关键类和扩展接口的介绍,本文主要是debug代码来看spring是如何初始化以及在分别在何时输出上文 demo中各扩展点的日志。
本文分为两部分:《spring初始化源码浅析之关键类和扩展接口》、《spring初始化源码浅析之代码浅析》
1、refresh()简介
通过ClassPathXmlApplicationContext构造方法进入 refresh方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//容器刷新前做一些准备工作
prepareRefresh();
// 创建DefaultListableBeanFactory对象,解析出所有BeanDefinition信息,
//注册缓存在DefaultListableBeanFactory的beanDefinitionMap属性中,供后面创建bean对象时使用
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 为beanFactory提供一些标准配置,如:类加载器、环境变量等
prepareBeanFactory(beanFactory);
try {
// 为beanFactory提供一些个性配置,通过在子上下文中复写该方法来实现
postProcessBeanFactory(beanFactory);
//创建实现BeanFactoryPostProcessor的实现类,并执行接口的方法。
//该方法执行完后会输出实例中的1-7步的日志
invokeBeanFactoryPostProcessors(beanFactory);
//创建BeanPostProcessor的实现类,并注册到BeanFactoryPostProcessor的beanPostProcessors列表中,
//在后面创建普通非lazy对象时会遍历该列表回调前置和后置方法
registerBeanPostProcessors(beanFactory);
//跟国际化消息相关,没去研究过
initMessageSource();
//初始化该上下文的事件广播
initApplicationEventMulticaster();
//模板方法,在不同的容器刷新的时候可以自定义逻辑
onRefresh();
//创建ApplicationListener的实现类,并注册到该上下文中
registerListeners();
//完成所有剩余的非lazy的bean的创建
finishBeanFactoryInitialization(beanFactory);
//上下文的创建完成的一些设置和缓存清理,并发布创建完成事件
finishRefresh();
}catch (BeansException ex) {
……
}finally {
//Reset common introspection caches in Spring's core, since we
//might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
2、关键代码跟踪
先看《spring初始化源码浅析之关键类和扩展接口》文中代码执行结果:
2.1、obtainFreshBeanFactory()代码分析
首先找到beanFactory的入口方法,如下
继续debug进入refreshBeanFactory方法,如下
从下图中可以看到,XmlBeanDefinitionReader为加载BeanDefinition的关键类,而将beanFactoy作为构造参数主要是为了将创建好的BeanDefinition对象注册到beanFactory中,后面会贴出相应的代码,如下
继续断点进入XmlBeanDefinitionReader的loadBeanDefinitions方法,可见入参为main方法中的指定配置文件的名称,如下
断点继续走,跳过将applicationContext.xml文件解析成Document的过程,进入registerBeanDefinitions(Document doc, Resource resource)方法,入参为applicationContext.xml对应的Document对象,该方法构造一个BeanDefinitionDocumentReader对象来具体的负责从doc对象创建BeanDefinition对象,并注册到beanFactory中,如下
注意 BeanDefinitionDocumentReader的registerBeanDefinitions方法一个入参为XmlReaderContext对象,该对象的reader即为前面创建XmlBeanDefinitionReader对象。
继续断点进入以下方法:
最后进入DefaultListableBeanFactory的registerBeanDefinition方法,最后将创建好的BeanDefinition对象缓存到DefaultListableBeanFactory的一个ConcurrentHashMap中
最终将配置文件中所有的bean配置转成BeanDefinition对象缓存起来,供后面创建具体的bean对象使用。
2.2、invokeBeanFactoryPostProcessors(beanFactory)代码分析
进入方法发现逻辑都交给PostProcessorRegistrationDelegate类来处理:
断点一直走到下面方法,先尝试从单利的缓存中去找,找不到再通过单例工厂类创建对象:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
………………
singletonObject = singletonFactory.getObject();
newSingleton = true;
…………
if (newSingleton) {
//添加到单例缓存中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
//由于缓存单例对象的 hashmap没有hellword对象,进入singletonFactory.getObject()方法 ,
//继续断点到 AbstractAutowireCapableBeanFactory的doCreateBean放法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建bean对象的包装器,beanName=hellowordService,
//该方法执行完成后输出第一步日志:1->HelloWorldService constructor
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();//创建bean对象
…………
try {
//从RootBeanDefinition 获取属性信息并填充到instanceWrapper对象
populateBean(beanName, mbd, instanceWrapper);
//进入初始化bean对象的操作
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
…………
//将创建好的bean对象注册到缓存起来
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
…………
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 开始调用各种ware接口的方法,会输出2、3、4步的日志
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//执行BeanPostProcessor的前置方法postProcessBeforeInitialization,由于
//ApplicationContextAwareProcessor实现该接口,该类中会执行很多*Aware的类,而hellwordService
//实现ApplicationContextAware类,所在会输出:4->ApplicationContextAware.setApplicationContext:
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//init bean对象
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//执行BeanPostProcessor的后置方法postProcessAfterInitialization,
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
//日志输出 2->BeanNameAware.setBeanName:helloWorldService
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
//日志输出 3->BeanFactoryAware.setBeanFactory:
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
…………
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//日志输出:5->InitializingBean.afterPropertiesSet
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//执行自定义init method方法,输出日志 :6->init method
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
}
最后回到getSingleton方法:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
……
//添加到单例缓存中
addSingleton(beanName, singletonObject);
}
hellwordService对象创建完毕后,便执行 下一步的invokeBeanFactoryPostProcessors方法,输出第7步日志:
7->BeanFactoryPostProcessor.postProcessBeanFactory 将peopleService的content属性修改为i am ok
到此为止,invokeBeanFactoryPostProcessors(beanFactory);执行完毕
2.3、registerBeanPostProcessors(beanFactory)代码分析
可以看到代码和invokeBeanFactoryPostProcessors(beanFactory)的代码模式几乎一样,在本方法中会创建所有实现BeanPostProcessor接口类并注册到beanFactory中供后面对象创建时回调,代码不再做分析
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
2.4、registerListeners();代码分析
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
//hellowordService便在此处注册
getApplicationEventMulticaster().addApplicationListener(listener);
}
…………
}
2.5、finishBeanFactoryInitialization(beanFactory)代码分析
断点直接进入一下代码:
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
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 {
//所有非lazy对象便在此处创建,如实例中的peopleServcie,对象创建过程前面已分析
//peopleServcie的创建过程回掉beanpostProcessors的前置和后置方法,输出日志:
//8->BeanPostProcessor.postProcessBeforeInitialization->peopleService
//9->BeanPostProcessor.postProcessAfterInitialization->peopleService
getBean(beanName);
}
}
}
…………
}
2.4、finishRefresh()代码分析
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
//发布ContextRefreshedEvent事件,输入日志
//10->ApplicationListener.onApplicationEvent:
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
到此代码分析完毕,以上只是简要的分析了初始化过程中关键代码,还有很多细节大家可自己断点跟踪。