书接前文:Spring源码之三——refresh方法之obtainFreshBeanFactory()
接下来,我们来看一下refresh方法中的prepareBeanFactory()方法,此方法主要用来配置工厂的标准上下文特征,例如上下文的 ClassLoader 和后处理器。话不多说,直接看具体实现。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置用于加载 bean 类的类加载器。 默认是线程上下文类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//指定 bean 定义值中表达式的解析策略
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//添加要应用于所有 bean 创建过程的 PropertyEditorRegistrar
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加一个新的 BeanPostProcessor,它将应用于此工厂创建的 bean。 在出厂配置期间调用。
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//忽略给定的自动装配依赖的EnvironmentAware接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
//忽略给定的自动装配依赖的EmbeddedValueResolverAware接口
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
//忽略给定的自动装配依赖的ResourceLoaderAware接口
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
//忽略给定的自动装配依赖的ApplicationEventPublisherAware接口
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
//忽略给定的自动装配依赖的MessageSourceAware接口
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
//忽略给定的自动装配依赖的ApplicationContextAware接口
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
//使用相应的自动装配值注册一个BeanFactory依赖类型
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
//使用相应的自动装配值注册一个ResourceLoader依赖类型
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
//使用相应的自动装配值注册一个ApplicationEventPublisher依赖类型
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
//使用相应的自动装配值注册一个ApplicationContext依赖类型
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//添加一个新的 BeanPostProcessor,它将应用于此工厂创建的 bean。 在出厂配置期间调用,为检测ApplicationListeners内部bean
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//这个 bean 工厂是否包含具有给定名称的 bean 定义或外部注册的单例实例?如果给定的名称是别名,它将被转换回相应的规范 bean 名称。如果这个工厂是分层的,如果在这个工厂实例中找不到 bean,将询问任何父工厂。
//如果找到与给定名称匹配的 bean 定义或单例实例,则无论命名的 bean 定义是具体的还是抽象的、惰性的还是急切的、范围内的,此方法都将返回true 。 因此,请注意,此方法的true返回值并不一定表示getBean将能够获得同名的实例。
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
//指定用于类型匹配目的的临时类加载器。 默认为 none,只需使用标准 bean 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());
}
}
可能看了以上的实现,觉得似懂非懂,下面我挑选一些主要来解释下。
(1)设置bean的类加载器,这里没啥好说的。要想后续加载一个bean,肯定需要先获取bean的类加载器。
beanFactory.setBeanClassLoader(getClassLoader());
public class DefaultResourceLoader implements ResourceLoader {
//省略部分代码......
@Override
@Nullable
public ClassLoader getClassLoader() {
return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader());
}
}
(2)StandardBeanExpressionResolver对象,用于解析形如 #{...}的SpEL表达式,这是一种比JSP中EL更高级的表达式。比如我们通常在application.xml中配置一个变量,在java中使用 @Value("#{表达式}")引用此变量。
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
(3)ResourceEditorRegistrar类,主要用于注册用户自定义的PropertyEditor实现类。
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
(4)addBeanPostProcessor方法,添加一个ApplicationContextAwareProcessor的实例化对象到bean后置处理器(即:List<BeanPostProcessor> beanPostProcessors)中。接着,忽略给定接口实现类是忽略指定接口(UserAwre)的set方法的自动装配。
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//忽略给定的自动装配依赖的EnvironmentAware接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
//忽略给定的自动装配依赖的EmbeddedValueResolverAware接口
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
//忽略给定的自动装配依赖的ResourceLoaderAware接口
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
//忽略给定的自动装配依赖的ApplicationEventPublisherAware接口
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
//忽略给定的自动装配依赖的MessageSourceAware接口
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
//忽略给定的自动装配依赖的ApplicationContextAware接口
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
(5)为何要注册如下几个bean呢,是因为它们是spring容器初始化需要用到的内部bean,不出现在配置文件中,所以此处需要spring自行注册。
//使用相应的自动装配值注册一个BeanFactory依赖类型
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
//使用相应的自动装配值注册一个ResourceLoader依赖类型
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
//使用相应的自动装配值注册一个ApplicationEventPublisher依赖类型
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
//使用相应的自动装配值注册一个ApplicationContext依赖类型
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
(6)添加bean的后置处理器。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
(7) 判断容器中存在名为"loadTimeWeaver"的bean,如果有则则添加一个作用域为loadTimeWeaver(代码织入)的后置处理器,在后续AOP解析中详细讲解,此处略。
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
//指定用于类型匹配目的的临时类加载器。 默认为 none,只需使用标准 bean ClassLoader
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
(8)判断容器中存在名为"environment"、“systemProperties”、”systemEnvironment”的bean,如果有则注册对应的单例bean。
//根据环境或系统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());
}
prepareBeanFactory()方法,至此结束。