Spring 源码阅读笔记(五)
前篇导航
Spring 源码阅读笔记(一)
Spring 源码阅读笔记(二)
Spring 源码阅读笔记(三)
Spring 源码阅读笔记(四)
前篇回顾
在上一篇章节中,由于后面的需要,我们穿插了一篇文章,来讲BeanDefinition的创建和Definition进入DefaultListableBeanFactory中。最终是把BeanDefinition放入了BeanDefinitionMap中。
在这里值得一提的是,BeanDefinition对象中,有一个属性,BeanClass,他是一个Object类型,在createBeanDefinition方法是设置的className属性,在内部实现中,他直接把String赋值给了BeanClass对象,在使用时会instanceof的。
正式开始
后面这篇文章正式开始,在这篇文章中会开始对prepareBeanFactory方法进行解读,在Refresh方法中,是第三个方法。
// Prepare the bean factory for use in this context.
// 准备 bean 工厂以在此上下文中使用。
prepareBeanFactory(beanFactory);
根据这个方法上面的注释,我产生一个疑问,不知道他在准备什么Bean工厂,因为在上篇文章中,他已经拿到了一个Bean工厂,并且还设置了BeanDefinition在里面。这个时候我带着问题向下看。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 告诉内部 bean 工厂使用上下文的类加载器等。
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 使用上下文回调配置 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.ignoreDependencyInterface(ApplicationStartupAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// BeanFactory 接口未在普通工厂中注册为可解析类型。
// MessageSource registered (and found for autowiring) as a bean.
// MessageSource 作为 bean 注册(并为自动装配找到)。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
// 将用于检测内部 bean 的早期后处理器注册为 ApplicationListener。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 检测 LoadTimeWeaver 并准备编织(如果找到)。
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
// 为类型匹配设置一个临时 ClassLoader。
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
// 注册默认环境 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());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
在这个代码块中,可以发现的是代码注释很多,这意味着我们少了一些阅读困难
不过大致读了一下,心里只有一个反应这都是个啥,一堆设置信息,怪不得开头叫准备Bean工厂。读这一代码我们还是采取像之前的分段阅读模式。
第一段代码
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
通过上方代码,先是给Beanfactory中设置了一个classloader,盲猜是用来创建Bean用的。
进入if,根据字面意思是,要不要忽略el表达式。,通过properties文件去查找spring.spel.ignore属性,我们没有设置,此处为false,判断去反,进入进入环节。设置了一个ExpressionResolver(表达式解析器)。StandardBeanExpressionResolver内部是SpelExpressionParser。
最后一行是向Bean工厂中添加了一个PropertyEditorRegister,具体做什么的目前不知道,这个类型是resourceEditorRegister。这里不知道是一个责任链还是一个观察者。看面看用到他的地方发吧,
第二段代码
// 使用上下文回调配置 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.ignoreDependencyInterface(ApplicationStartupAware.class);
这一段代码除了第一行代码不一样,其他的基本一致
看到第一行代码,用过Spring应该都知道,BeanPostProcessor,这里就是向Bean工厂中添加了一个ApplicationContextAwareProcessor。这个类也很简单。我大致解读一下,我们之间可能有接触过的。
小插曲
private void invokeAwareInterfaces(Object bean) {
// ... 一堆if
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
我在写Spring项目的时候都遇到过要通过ApplicationContext来获取Bean,那么怎么获取ApplicationContext,我们大部分人用的就是创建一个类,实现ApplicationContextArare接口,然后就可以获取了。原因是什么呢,就是这里了。在Spring把ApplicationContextAware接口实例化后,会有一个PostProcessor去调用它里面的setApplicationContext方法。
回到正轨
在设置完ApplicationContextAwareProcessor后,调用了一堆ignoreDependencyInterface方法,传入方法的实体类都是ApplicationContextAwareProcessor中涉及到的接口,具体这个方法看实现只是向一个HashSet中添加值,这个属性后面遇到了再进行探讨。
第三段代码
// BeanFactory interface not registered as resolvable type in a plain factory.
// BeanFactory 接口未在普通工厂中注册为可解析类型。
// MessageSource registered (and found for autowiring) as a bean.
// MessageSource 作为 bean 注册(并为自动装配找到)。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
调用了一堆registerResolvableDependency方法,这里做记录,后面说不定用得到。可能作为容器使用。
第四段代码
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
这里又添加了一个BeanPostProcess,看New出来的类名,和在Refresh中的第一个方法中的观察者模式有关系。
第五段代码
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
// 为类型匹配设置一个临时 ClassLoader。
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
这段代码和loadTimeWeaver有关,至于loadTimeWeaver是什么可以自己去了解下,或者我我后面开篇文章来讲一下。这里由于我们没有设置,可以跳过。
第六段代码。
// Register default environment beans.
// 注册默认环境 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());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
看这段代码很简单,我在疑惑containsLocalBean方法是什么意思。在这里要解释一下,BeanFactory他是有继承关系的。在Bean接口中他有如下的解释。
Return whether the local bean factory contains a bean of the given name, ignoring beans defined in ancestor contexts.
大概的意思就是,检查当前的facotry中有没有这个Bean,不考虑他的祖先工厂中是否存在。
那么这段代码就可以看明白了,如果当前工厂中不存在这些Bean的话,就以单例的形式,在当前的Bean Factory中重新注册一个。
告一段落
到这里这篇文章就结束了,那么正如方法开头的注释一样。
Prepare the bean factory for use in this context.
准备 bean 工厂以在此上下文中使用。
结束语
写文章的目的是为了帮助自己巩固知识,写的不好或者错误的地方可以在评论区指出。如果您看了文章觉得对您有所帮助可以点个赞,如果发现有些问题产生了疑惑,或者不明白的可以评论,一定知无不言。当然也希望和大家交个朋友,相互学习。