Spring源码解析(二)Refresh()方法(一)

360 阅读5分钟

前言: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());
		}
		// ...省略部分
	}

主要做了如下工作:

  1. 设置一个类加载器
  2. bean的表达式解析,能够获取bean当中的属性,在前台页面
  3. 设置对象与字符串之间的转换的类
  4. 添加了一个后置处理器:ApplicationContextAwareProcessor,其实现了接口BeanPostProcessor(其作为spring扩展点之一,这个接口会在后面详细讲解的)
  5. 设置忽略自动装配的接口
  6. 相关依赖的替换
  7. 设置一些系统配置和系统环境信息

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方法时,从截图可以清楚看到里面并没有内容

image-20201222211401516.png

当我们在Test类中的main方法中调用addBeanFactoryPostProcessor()方法时:

image-20201222211819682.png

可以从下图看出结果:

image-20201222212534962.png


本篇文章到这就完结,后面的内容,下篇文章再写。希望我能更新更快一点(逃

2. 参考链接

剑指Spring源码(二)