/**
* 客户表现层
*/
public class CustomerController {
public static void main(String[] args) {
// 1.加载spring 配置文件,初始化创建ioc容器
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");
// 2.从ioc容器获取service
CustomerService customerService = (CustomerService)context.getBean("customerService");
// 3.保存客户操作
customerService.saveCustomer();
}
}
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext { // 资源配置文件成员变量,是一个数组,支持多个spring的配置文件
@Nullable
private Resource[] configResources;
// 默认构造方法
public ClassPathXmlApplicationContext() {
}
// 如果已经存在一个ioc容器,可以在构造的时候设置【父】容器
public ClassPathXmlApplicationContext(ApplicationContext parent) {
super(parent);
}
// 【重点跟踪】根据xxx.xml配置文件,创建ioc容器
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[]{configLocation}, true, (ApplicationContext)null);
}
..........................................
/**
*【重点跟踪】方法说明:
* 根据xml文件的定义,以及父容器,创建一个新的ClassPathXmlApplicationContext
*
*参数说明:
* configLocations:xml配置文件数组
* refresh:是否要重新创建ioc容器。加载全部bean的定义和创建所有的单例对象
* parent:父容器
*/
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
super(parent);// 设置父容器
// 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割)
this.setConfigLocations(configLocations);
if (refresh) {
this.refresh();// 【核心方法】:该方法表示初始化(或者重建)ioc容器。即可以把原来的ApplicationContext销毁,重新执行初始化创建
}
}
..........................................
}
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
..........................................
/**
*【重点跟踪】方法说明:
* 【核心方法】:该方法表示初始化(或者重建)ioc容器。即可以把原来的ApplicationContext销毁,重新执行初始化创建
*/
public void refresh() throws BeansException, IllegalStateException {
// 创建ioc容器,同步加锁,保障线程安全
synchronized (this.startupShutdownMonitor) {
// 准备工作:记录容器启动的时间,和状态标记
prepareRefresh();
// 关键步骤:
// 1.根据配置文件中配置内容,解析成一个个Bean实例(BeanDefinition)
// 2.将一个个Bean实例,注册到BeanFactory中
// 3.细节:这里的Bean实例仅仅是描述Bean的相关信息,此时还没有真正创建对应的bean对象
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置BeanFactory:
// 1.设置类加载器
// 2.设置BeanPostProcessor(bean后置处理器)
// 3.注册特殊的bean(框架内部使用的bean)
prepareBeanFactory(beanFactory);
try {
// 设置BeanFactoryPostProcessor
postProcessBeanFactory(beanFactory);
// 调用BeanFactoryPostProcessor各个实现类的 postProcessBeanFactory(factory) 方法
// 与上一步合起来,可以理解为是给Bean提供的一种扩展机制。比如可以让我们的Bean实现BeanFactoryPostProcessor接口,增强该Bean的功能
invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessor的实现类:
// 1.该接口有两个方法:
// postProcessBeforeInitialization(),在init-method属性指定的方法前调用
// postProcessAfterInitialization(),在init-method属性指定的方法后调用
registerBeanPostProcessors(beanFactory);
// 初始化国际化支持的资源文件
initMessageSource();
// 初始化ApplicationContext事件广播器
initApplicationEventMulticaster();
// 模板方法:用于特殊bean的初始化,默认是空实现(在api中如果预留了一些方法实现是空,表示该方法是留给子类自我实现。那么这些方法称为:钩子方法)
onRefresh();
// 注册事件监听器:监听器需要实现ApplicationListener接口
registerListeners();
// 【重点步骤】:
// 1.实例化所有单例bean对象,除开延迟加载的bean
// <bean id="customerDao" class="com.itheima.dao.impl.CustomerDaoImpl" lazy-init="false" scope="singleton"/>
finishBeanFactoryInitialization(beanFactory);
// 【最后一步】:
// 1.发布广播事件。ApplicationContext初始化完成
finishRefresh();
}catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 如果发生异常,需要销毁已经创建的singleton对象
destroyBeans();
// 将active状态设置为false
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
..........................................
}
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |