一、代码入口
3.1版本之前获取bean的方式:
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));
bf.getBean("testBean");
3.1版本之后XmlBeanFactory废弃所以推荐采用ApplicationContext获取bean:本章主要介绍此种获取bean的方式,ApplicationContext BeanFacotry 两者都是用于加载 Bean 的,但是相比之下, ApplicationContext 提供了更多的扩展功能,简单点说 Application Context包含BeanFactory 的所有功能
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("testApplicationContext.xml");
TestBean testBean = (TestBean) applicationContext.getBean("testBean");
ps:beanFactory废弃原因:
(1)XmlBeanFactory对作用于的支持单一
(2)BeanFactory只支持两个作用域——Singleton和Prototype。
(3)XmlBeanFactory延迟加载 在企业及的项目当中,我们对bean的需求往往是比较大的,如果了解延迟加载的朋友,想必了解,延迟加载确实会给我们启动释放很多的压力,但是当我们在运行的时候,大量加载的时候,也会出现性能瓶颈
(4)XmlBeanFactory不会自动注册接口。
(5)XmlBeanFactory在企业级项目里面,并没有太好的支持
二、 类图全貌![](https://i-blog.csdnimg.cn/blog_migrate/9b9376a45147d102021d9d6232847dbf.png)
三、源码解析:
1.ClassPathXmlApplicationContext的构造函数
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
从第二段代码开始看,总共就做了三件事:
(1)super(parent)
设置一下父级ApplicationContext,这里是null
(2)setConfigLocations(configLocations)
里面做了两件事情:
1. 将指定的Spring配置文件的路径存储到本地
2.解析Spring配置文件路径中的${PlaceHolder}占位符,替换为系统变量中PlaceHolder对应的Value值,System本身就自带一些系统变量比如class.path、os.name、user.dir等,也可以通过System.setProperty()方法设置自己需要的系统变量
(3)refresh()
这个就是整个Spring Bean加载的核心了,它是ClassPathXmlApplicationContext的父类AbstractApplicationContext的一个方法,顾名思义,用于刷新整个Spring上下文信息,定义了整个Spring上下文加载的流程。
2.refresh方法
上面已经说了,refresh()方法是整个Spring Bean加载的核心
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备此上下文以进行刷新。
prepareRefresh();
// 告诉子类刷新内部 bean 工厂。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备在此上下文中使用的 bean 工厂。
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对 bean 工厂进行后处理。一个空的函数方便程序员扩展
postProcessBeanFactory(beanFactory);
// 调用在上下文中注册为 bean 的工厂处理器。激活各种 BeanFactory 处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截 bean 创建的 bean 处理器。这里只是注册,真正的调用是在getBean时候
registerBeanPostProcessors(beanFactory);
// 为此上下文初始化消息源。为上下文初始化 Message源,即对不同语言的消息体进行国际化处理
initMessageSource();
// 为此上下文初始化事件多播器。
initApplicationEventMulticaster();
// 初始化特定上下文子类中的其他特殊 bean
onRefresh();
// 检查侦听器 bean 并注册它们。
registerListeners();
// 实例化所有剩余的(非延迟初始化)单例。
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布相应的事件。完成刷新过程,通知生命周期处理lifecycleProcessor 刷新过程,同时发出 ContextRefreshEvent 通知别人
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经创建的单例以避免空资源。
destroyBeans();
// 重置“活动”标志。
cancelRefresh(ex);
// 将异常传播给调用者。
throw ex;
}
finally {
// 重置 Spring 核心中的常见内省缓存,因为我们可能不再需要单例 bean 的元数据......
resetCommonCaches();
}
}
}
startUpShutdownMonitor对象是加锁的,这么做的原因是避免多线程同时刷新Spring上下文,而后续close()方法也是用的该对象锁,所以可以避免冲突
下面简单介绍核心的方法
(1)obtainFreshBeanFactory方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
告诉子类刷新内部 bean 工厂。
返回:新建的 BeanFactory 实例
下面其中的refreshBeanFactory()方法
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
该方法中DefaultListableBeanFactory 类非常重要,后面会详讲,先继续看其他方法refresh()中的其他方法
(3)prepareBeanFactory方法
上一步已经把工厂建好了,但是还不能投入使用,因为工厂里什么都没有,还需要配置一些东西。看看这个方法的注释
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//设置BeanFactory的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//设置支持表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xx,因为ApplicationContextAwareProcessor#invokeAwareInterfaces已经把这5个接口的实现工作做了
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、ResourceLoader、ApplicationEventPublisher、ApplicationContext
//其他组件中可以通过 @autowired 直接注册使用
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//添加BeanPostProcessor【ApplicationListenerDetector】后置处理器,在bean初始化前后的一些工作
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()));
}
//给BeanFactory中注册一些能用的组件;
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
//环境信息ConfigurableEnvironment
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
//系统属性,systemProperties【Map<String, Object>】
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
//系统环境变量systemEnvironment【Map<String, Object>】
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}