You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
4.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

ClassPathXmlApplicationContext
super(parent);// 调用父类构造方法,进行相关的对象创建等操作,包含属性的赋值操作
setConfigLocations(configLocations);//设置应用程序上下文的配置路径
refresh();//13个核心方法
/**
前戏,做容器刷新前的准备工作
1、设置容器的启动时间
2、设置活跃状态为true
3、设置关闭状态为false
4、获取Environment对象并加载当前系统的属性值到Environment对象中
5、准备监听器和事件的集合对象默认为空的集合
*/
/**
备注:
准备过程中可以通过实现接口和子类继承做增强工作修改一些配置类似于AOP
*/
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 创建容器对象DefaultListableBeanFactory
// 加载xml配置文件的属性值到当前工厂中最重要的就是BeanDefinition
/**备注:
ClassPathXmlApplicationContext重载了多个方法传不同的参有不同的实现且过程中有环境变量的替换还可以设置是否循环依赖和是否可以覆盖修改方法通过集成空的父类重写方法实现。
例如MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext重写方法解析过程loadBeanDefinitions/重载比较多,就是用于解析配置文件的)
ClassPathXmlApplicationContext(String[])传入的是string数组
String[]-String-resource[]-resource
通过resource获取文档document并获取跟节点循环遍历子节点
遍历过程中判断默认命名空间和自定义命名空间进行不同的处理方式解析
并且把值注册到beanFactory
*/
/**
自定义命名空间(扩展思路)
首先在spring.handlers中定义自定义标签的K和V(K:网址,V:对应的类)
例如:"http://www.springframework.org/schema/context"->"org.springframework.context.config.ContextNamespaceHandler"
然后在实现的hadler类中继承NamespaceHandlerSupport重写init方法。
在init方法中指定标签属性对应的parse解析类
例如:registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
然后内部会根据上述扩展获取对应的hadler字符串再反射生成类然后在调用重写的init方法将扩展指定好的parse类注册到map中
*/
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.
// 子类覆盖方法做额外的处理此处我们自己一般不做任何扩展工作但是可以查看web中的代码是有具体实现的
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 调用各种beanFactory处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册bean处理器这里只是注册功能真正调用的是getBean方法
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 为上下文初始化message源即不同语言的消息体国际化处理,在springmvc的时候通过国际化的代码重点讲
initMessageSource();
// Initialize event multicaster for this context.
// 初始化事件监听多路广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 留给子类来初始化其他的bean
onRefresh();
// Check for listener beans and register them.
// 在所有注册的bean中查找listener bean,注册到消息广播器中
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 初始化剩下的单实例(非懒加载的)
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 完成刷新过程通知生命周期处理器lifecycleProcessor刷新过程同时发出ContextRefreshEvent通知别人
finishRefresh();
}