chapter06_应用上下文与门面模式
一、应用上下文
目前对Spring的使用,还是太复杂
- 先要知道BeanFactory接口的最终实现类,DefaultListableBeanFactory
- 还要创建XmlBeanDefinitionReader,读取BeanDefinition
@Test
public void testGetBeanFromXml() {// 1.初始化 BeanFactoryDefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();// 2. 读取配置文件&注册BeanXmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);reader.loadBeanDefinitions("classpath:spring.xml");// 3. 获取Bean对象调用方法Person person = (Person) beanFactory.getBean("person");System.out.println("person:" + person);
}
对外提供一个上下文,屏蔽掉DefaultListableBeanFactory与XmlBeanDefinitionReader,让外界使用只需要一行代码即可使用spring,这就是门面设计模式,对外提供一个统一接口,屏蔽掉内部实现细节
- 门面内部会帮我们调用Spring各个子系统,完成具体的功能
- 门面内部还可以给BeanFactory增加更多的功能,例如Bean的各种前置、后置处理器
- 使用门面模式后,对用户而言,可以更加方便的使用BeanFactory
二、新建ApplicationContext
首先新建一个接口ListableBeanFactory,继承BeanFactory接口,扩展一个根据类型获取所有的Bean实例
public interface ListableBeanFactory extends BeanFactory{/*** 返回指定类型的所有实例** @param type* @param <T>* @return*/<T> Map<String, T> getBeansOfType(Class<T> type);
}
新建ApplicationContext接口,继承ListableBeanFactory,这样ApplicationContext就具备了getBean的能力
public interface ApplicationContext extends ListableBeanFactory {
}
新建ConfigurableApplicationContext接口,继承ApplicationContext接口
- ApplicationContext本身是一个只读接口
- 扩展后,允许彻底销毁并重新创建 BeanFactory,重新加载配置
- refresh是Spring生命周期的关键方法
public interface ConfigurableApplicationContext extends ApplicationContext {void refresh();
}
新建AbstractApplicationContext,使用模板方法设计模式(类似于AbstractBeanFactory),实现refresh和三个getBean方法
- refreshBeanFactory,创建BeanFactory并加载BeanDefinition,交给子类实现
- getBeanFactory,交给子类实现
- 扩展点一,BeanFactoryPostProcessor,在所有的 BeanDefinition 加载完成后,实例化 Bean 对象之前,提供修改 BeanDefinition 属性的机制
- 扩展点二,BeanPostProcessor,提供初始化前和初始化后修改Bean的能力
- 实例化所有的Bean对象
定义两个抽象方法refreshBeanFactory,getBeanFactory,交给子类实现
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {@Overridepublic void refresh() {//创建BeanFactory,并扫描BeanDefinitionrefreshBeanFactory();ConfigurableListableBeanFactory beanFactory = getBeanFactory();//在bean实例化之前,执行BeanFactoryPostProcessorinvokeBeanFactoryPostProcessors(beanFactory);//BeanPostProcessor需要提前于其他bean实例化之前注册registerBeanPostProcessors(beanFactory);//提前实例化单例beanbeanFactory.preInstantiateSingletons();}/*** 创建BeanFactory,并加载BeanDefinition*/protected abstract void refreshBeanFactory();public abstract ConfigurableListableBeanFactory getBeanFactory();/*** 在bean实例化之前,执行BeanFactoryPostProcessor** @param beanFactory*/protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessorMap.values()) {beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);}}/*** 注册BeanPostProcessor** @param beanFactory*/protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) {beanFactory.addBeanPostProcessor(beanPostProcessor);}}@Overridepublic Object getBean(String name, Object... args) {return getBeanFactory().getBean(name, args);}@Overridepublic <T> Map<String, T> getBeansOfType(Class<T> type) {return getBeanFactory().getBeansOfType(type);}public Object getBean(String name) {return getBeanFactory().getBean(name);}
}
BeanFactoryPostProcessor对BeanDefinition修改的原理
- 直接调用了invokeBeanFactoryPostProcessors,调用了getBeansOfType
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessorMap.values()) {beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);}}
- getBeansOfType,最终还是调用了getBean,提前将BeanFactoryPostProcessor类型的Bean创建了
@Override
public <T> Map<String, T> getBeansOfType(Class<T> type) {Map<String, T> result = new HashMap<>();beanDefinitionMap.forEach((beanName, beanDefinition) -> {Class beanClass = beanDefinition.getBeanClass();if (type.isAssignableFrom(beanClass)) {T bean = (T) getBean(beanName);result.put(beanName, bean);}});return result;
}
BeanFactoryProcessor对Bean修改的原理
- 在refresh的时候,先将BeanFactoryProcessor类型的Bean实例化
/*** 注册BeanPostProcessor** @param beanFactory*/protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) {beanFactory.addBeanPostProcessor(beanPostProcessor);}}
注册BeanPostProcessor,并在实例化Bean的时候,调用
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {//有则覆盖this.beanPostProcessors.remove(beanPostProcessor);this.beanPostProcessors.add(beanPostProcessor);
}
容易让人疑惑的地方,BeanFactoryPostProcessor和BeanPostProcessor自己也是Bean,自己getBeansOfType也要先实例化
- BeanFactoryPostProcessor实例化的时候,BeanPostProcessor还没有注册,此时没有BeanPostProcessor,不会调用
- BeanPostProcessor实例化的时候,可能已经有其它BeanPostProcessor注册了,所以会有BeanPostProcessor匹配上,所以BeanPostProcessor代码一定要写明确,对特定的类型进行初始化修改,避免引起歧义
新建AbstractRefreshableApplicationContext,实现上述两个抽象方法
- 本类的任务就是完成Refresh功能
- refreshBeanFactory的时候,会重新创建一个DefaultListableBeanFactory,调用loadBeanDefinitions抽象方法
- getBeanFactory的时候,直接返回刚刚创建的BeanFactory
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {private DefaultListableBeanFactory beanFactory;@Overrideprotected void refreshBeanFactory() {DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();loadBeanDefinitions(beanFactory);this.beanFactory = beanFactory;}/*** 加载BeanDefinition** @param beanFactory*/protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory);@Overridepublic DefaultListableBeanFactory getBeanFactory() {return beanFactory;}
}
新建AbstractXmlApplicationContext,完成loadBeanDefinitions抽象方法
- 真正干活的是XmlBeanDefinitionReader,由它读取XML中的Bean定义
- 唯一不确定的是configLocations,继续将getConfigLocations交给子类实现
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableApplicationContext {@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory, this);String[] configLocations = getConfigLocations();if (configLocations != null) {beanDefinitionReader.loadBeanDefinitions(configLocations);}}protected abstract String[] getConfigLocations();
}
新建ClassPathXmlApplicationContext,继承AbstractXmlApplicationContext
- 构造函数里面做了两件事情,保存xml文件的路径,调用refresh()方法
- 实现父类的抽象方法getConfigLocations
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext{private String[] configLocations;/*** 从xml文件加载BeanDefinition,并且自动刷新上下文** @param configLocation xml配置文件*/public ClassPathXmlApplicationContext(String configLocation) {this(new String[]{configLocation});}/*** 从xml文件加载BeanDefinition,并且自动刷新上下文** @param configLocations xml配置文件*/public ClassPathXmlApplicationContext(String[] configLocations) {this.configLocations = configLocations;refresh();}@Overrideprotected String[] getConfigLocations() {return this.configLocations;}
}
三、重构BeanFactory
给AbstractBeanFactory类,新增管理BeanPostProcessors的功能
新建HierarchicalBeanFactory接口,继承BeanFactory接口
- 让BeanFactory支持“父子容器”层次结构
public interface HierarchicalBeanFactory extends BeanFactory{
}
新建ConfigurableBeanFactory接口,继承HierarchicalBeanFactory接口,让BeanFactory可配置化
- 本章节,扩展管理BeanPostProcessor的能力
- 后续章节,扩展销毁Bean的能力
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory {/*** @param beanPostProcessor*/void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
}
让AbstractBeanFactory类,实现ConfigurableBeanFactory接口
- 新增一个属性,保存beanPostProcessors,提供相应的get,set方法
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory {private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();······@Overridepublic void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {//有则覆盖this.beanPostProcessors.remove(beanPostProcessor);this.beanPostProcessors.add(beanPostProcessor);}public List<BeanPostProcessor> getBeanPostProcessors() {return beanPostProcessors;}
}
修改AbstractAutowireCapableBeanFactory,在Bean创建时完成前置、后置处理器的调用
- 修改createBean方法的业务流程,新增初始化initializeBean方法调用
- initializeBean方法是定义业务流程,包括初始化前和后的扩展
- 真正的初始化方法是invokeInitMethods
/*** 负责创建Bean** @Author 孤风雪影* @Email gitee.com/efairy520* @Date 2025/1/1 1:01* @Version 1.0*/
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {private final InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy();/*** 实现父类未实现的createBean方法* @param beanName* @param beanDefinition* @return*/@Overrideprotected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) {Object bean = doCreateBean(beanName, beanDefinition, args);populateBean(beanName, bean, beanDefinition);bean = initializeBean(beanName, bean, beanDefinition);addSingleton(beanName, bean);return bean;}protected Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) {//执行BeanPostProcessor的前置处理Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);//TODO 后面会在此处执行bean的初始化方法invokeInitMethods(beanName, wrappedBean, beanDefinition);//执行BeanPostProcessor的后置处理wrappedBean = applyBeanPostProcessorsAfterInitialization(bean, beanName);return wrappedBean;}/*** 执行bean的初始化方法** @param beanName* @param bean* @param beanDefinition* @throws Throwable*/protected void invokeInitMethods(String beanName, Object bean, BeanDefinition beanDefinition) {//TODO 后面会实现}·······@Overridepublic Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessBeforeInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;}@Overridepublic Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;}
}
四、测试类
新建MyBeanFactoryPostProcessor类
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {System.out.println("MyBeanFactoryPostProcessor#postProcessBeanFactory");//此后置处理器,修改person的名称BeanDefinition personBeanDefiniton = beanFactory.getBeanDefinition("person");PropertyValues propertyValues = personBeanDefiniton.getPropertyValues();//将person的name属性改为updatedpropertyValues.addPropertyValue(new PropertyValue("name", "MyBeanFactoryPostProcessor改为:Steven Curry"));}
}
新建MyBeanPostProcessor类
public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {if ("cat".equals(beanName)) {Cat cat = (Cat) bean;cat.setName("Bean后置初始化前改为:汤姆猫");}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {return null;}
}
新建springPostProcessor.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans><bean id="cat" class="cn.shopifymall.springframework.test.bean.Cat"><property name="name" value="tomcat"/><property name="weight" value="2000"/></bean><bean id="person" class="cn.shopifymall.springframework.test.bean.Person"><property name="name" value="LeBron James"/><property name="age" value="18"/><property name="cat" ref="cat"/></bean><bean class="cn.shopifymall.springframework.test.common.MyBeanPostProcessor"/><bean class="cn.shopifymall.springframework.test.common.MyBeanFactoryPostProcessor"/></beans>
测试类
public class ApiTest {@Testpublic void test_xml() {// 1.初始化 BeanFactoryClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:springPostProcessor.xml");// 2. 获取Bean对象调用方法Person person = (Person) applicationContext.getBean("person");System.out.println("测试结果:" + person);}
}
控制台输出
- 可以看出,两种类型的处理器都起作用了
MyBeanFactoryPostProcessor#postProcessBeanFactory
测试结果:Person(name=MyBeanFactoryPostProcessor改为:Steven Curry, age=18, cat=Cat(name=Bean后置初始化前改为:汤姆猫, weight=2000))
四、总结
整个Spring最重要的方法,refresh(),定义了Spring的生命周期
- 创建BeanFactory实现类
- 扫描BeanDefinition
- 扩展点一:调用BeanFactory后置处理器
- 扩展点二:注册Bean后置处理器
- 提前实例化所有的单例Bean
public void refresh() {//创建BeanFactory,并扫描BeanDefinitionrefreshBeanFactory();ConfigurableListableBeanFactory beanFactory = getBeanFactory();//在bean实例化之前,执行BeanFactoryPostProcessorinvokeBeanFactoryPostProcessors(beanFactory);//BeanPostProcessor需要提前于其他bean实例化之前注册registerBeanPostProcessors(beanFactory);//提前实例化单例beanbeanFactory.preInstantiateSingletons();
}
在Spring中,一切都是Bean,后置处理器本身也是Bean,也要注册到容器中
- 没有配置id的时候,beanName就是简单类名的首字母小写
实现上下文后的骨架
- 层1:缓存单例Bean
- 层2:串联上下游,管理BeanPostProcessor
- 层3:创建Bean
- 层4:管理BeanDefinition