本文是《Spring 手撸专栏》第 7 章学习笔记,主要记录我的一些debug调试过程,方便后期复习。具体学习,大家可以去看一下这个专栏,强烈推荐。
什么是应用上下文?
感觉就是增强版的容器,不仅可以管理对象,还可以提供其他更多的服务,比如解析配置信息
BeanFactory与ApplicationContext
- BeanFactory,这是最简单的容器,只能提供基本的DI功能;
- 继承了BeanFactory后派生而来的应用上下文,其抽象接口也就是我们上面提到的的ApplicationContext,它能提供更多企业级的服务,例如解析配置文本信息等等,这也是应用上下文实例对象最常见的应用场景。
- 应用上下文即是Spring容器抽象的一种实现;
今天我们要实现ClassPathXmlApplication,它可以从类路径下的一个或多个xml配置文件中加载上下文定义,适用于xml配置的方式;
设计
整体设计结构如下图:
● Spring 框架额外新增开发自己组建需求的两个必备接口: BeanFactoryPostProcess 和 BeanPostProcessor
● BeanFactoryPostProcessor,是由 Spring 框架组建提供的容器扩展机制,允许在 Bean 对象注册后但未实例化之前,对 Bean 的定义信息 BeanDefinition 执行修改操作。
● BeanPostProcessor,也是 Spring 提供的扩展机制,不过 BeanPostProcessor 是在 Bean 对象实例化之后修改 Bean 对象,也可以替换 Bean 对象。
同时上下文操作类要可以把相应的 XML 加载 、注册、实例化以及新增的修改和扩展都融合进去,让 Spring 可以自动扫描到我们的新增服务,便于用户使用
Spring 应用上下文和对Bean对象扩展机制的类关系
debug调试
起始
public void test_xml() {
// 1.初始化 BeanFactory (1)
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:springPostProcessor.xml");
// 2. 获取Bean对象调用方法
UserService userService = applicationContext.getBean("userService", UserService.class);
String result = userService.queryUserInfo();
System.out.println("测试结果:" + result);
}
(1) ClassPathXmlApplicationContext 主线1
从XML中加载BeanDefinition,并刷新上下文
public ClassPathXmlApplicationContext(String[] configLocations)throws BeansException{
this.configLocations = configLocations;
refresh();//(2)
}
(2)AbstractApplicationContext 主线2
刷新上下文的具体方法
public void refresh() throws BeansException {
//1 创建BeanFactory,并加载BeanDefinition
refreshBeanFactory();//(3)
//2 获取BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//3 在Bean实例化之前,执行BeanFactoryPostProcessor(调用在上下文中注册为bean的工厂处理器)
invokeBeanFactoryPostProcessors(beanFactory);//(5)
//4 BeanPostProcessor 需要提前于其他Bean对象实例化之前执行注册操作,会在这里
//实例化MyBeanPostProcessor
registerBeanPostProcessors(beanFactory);//(7)
//5 提前实例化单例Bean对象,会在这里调用MyBeanPostProcessor修改新实例化 Bean 对象
beanFactory.preInstantiateSingletons();//(9)
}
(3) AbstractRefreshableApplicationContext
创建BeanFactory,并加载BeanDefinition的具体方法
protected void refreshBeanFactory() throws BeansException {
DefaultListableBeanFactory beanFactory = createBeanFactory();
loadBeanDefinitions(beanFactory); //(4)
this.beanFactory = beanFactory;
}
补充:
正是在这里,实现了自动初始化BeanFactory,并为其注册Bean。我们无需自己手动操作
(4)AbstractXmlApplicationContext
上下文对配置信息的加载的具体方法,主要是读取xml配置,加载BeanDefinition
补充1:
最终真正解析xml,加载bean定义,自动注册是在XmlBeanDefinitionReader的doLoadBeanDefinitions中
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory, this);
String[] configLocations = getConfigLocations();
if (null != configLocations){
beanDefinitionReader.loadBeanDefinitions(configLocations);//补充1
}
}
(5) AbstractApplicationContext
在Bean实例化之前,执行我们子定义的MyBeanFactoryPostProcessor类,它实现了BeanFactoryPostProcessor接口
private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory){
//根据类型来取BeanFactoryPostProcessor,在这里可以取到我们自定义的MyBeanFactoryPostProcessor类
Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessorMap.values()){
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);(6)
}
}
(6)MyBeanFactoryPostProcessor
具体的postProcessor操作
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
PropertyValues propertyValues = beanDefinition.getPropertyValues();
propertyValues.addPropertyValue(new PropertyValue("company","改为:字节跳动"));
}
(7) AbstractApplicationContext
BeanPostProcessor 需要提前于其他Bean对象实例化之前执行注册操作
注意这里beanFactory.getBeansOfType()会实例化我们的MyBeanPostProcessor
private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory){
//根据类型来取BeanPostProcessor,在这里可以取到我们自定义的postProcessor类
Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()){
beanFactory.addBeanPostProcessor(beanPostProcessor);//(8)
}
}
(8) AbstractBeanFactory
注册BeanPostProcessor,将其添加进链表中
注意这里并没有调用我们自定义的MyBeanPostProcessor中的方法
//成员变量
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor){
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
}
(9)DefaultListableBeanFactory
这个类负责注册Bean定义与获取Bean定义
public void preInstantiateSingletons() throws BeansException {
beanDefinitionMap.keySet().forEach(this::getBean);//(10)
}
(10)AbstractBeanFactory
这个类负责对单例 Bean 对象的获取
public Object getBean(String name) throws BeansException{
return doGetBean(name, null);//(11)
}
(11)AbstractBeanFactory
protected <T> T doGetBean(final String name,final Object[] args){
Object bean = getSingleton(name);
if (bean != null){
return (T) bean;
}
BeanDefinition beanDefinition = getBeanDefinition(name);
return (T) creatBean(name,beanDefinition,args);//(12)
}
(12)AbstractAutowireCapableBeanFactory
这个类主要负责实现了 Bean 的实例化
利用反射进行bean的实例化
protected Object creatBean(String beanName,BeanDefinition beanDefinition,Object[] args) throws BeansException {
Object bean = null;
try {
bean = createBeanInstance(beanDefinition,beanName,args);
//给Bean填充属性
applyPropertyValues(beanName,bean,beanDefinition);
//执行Bean 的初始化方法和BeanPostProcessor的前置和后置处理方法
bean = initializeBean(beanName,bean,beanDefinition);//(13)
} catch (Exception e) {
throw new BeansException("Instantiation of bean failed",e);
}
addSingleton(beanName,bean);
return bean;
}
(13)AbstractAutowireCapableBeanFactory
执行Bean 的初始化方法和BeanPostProcessor的前置和后置处理方法
注意在这里才会调用MyBeanPostProcessor的方法
private Object initializeBean(String beanName,Object bean,BeanDefinition beanDefinition){
//1 执行BeanPostProcessor Before处理 (14)
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
//待完成内容:invokeInitMethods(beanName, wrappedBean, beanDefinition);
invokeInitMethods(beanName, wrappedBean, beanDefinition);
//2 执行BeanPostProcessor After处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
return wrappedBean;
}
(14)AbstractAutowireCapableBeanFactory
执行BeanPostProcessor Before处理
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()){
//(15)
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (null == current){
return result;
}
result = current;
}
return result;
}
(15)MyBeanPostProcessor
具体的执行BeanPostProcessor Before处理方法
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)){
UserService userService = (UserService) bean;
userService.setLocation("改为:北京");
}
return bean;
}