1. 为什么要有ApplicationContext详情请见 https://github.com/StrongChenYu/Tiny-Spring
ApplicationContext主要是为了将以下几个步骤(当然源spring中可能有更多)整合起来,放到一个容器中,提供生命周期管理。
- 读xml文件,进行bean的读取和beanDefinition的读取
- 注册postProcessor
- 注册BeanFactoryPostProcessor
- invoke BeanFactoryPostProcessor
如果不经过ApplicationContext,那么这一系列的过程大概是这样的,需要自己手动去注册路径,注册postprocessor等一系列的操作。
@Test
public void testBeanFactoryPostProcessorAndBeanPostProcessor() {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinition("classpath:spring.xml");
BeanFactoryPostProcessor myBeanFactoryPostProcessor = (BeanFactoryPostProcessor) factory.getBean("myBeanFactoryPostProcessor");
myBeanFactoryPostProcessor.postProcessBeanFactory(factory);
factory.addBeanPostProcessor((BeanPostProcessor) factory.getBean("myBeanPostProcessor"));
UserService userService = factory.getBean("userService", UserService.class);
System.out.println(userService);
}
而有了ApplicationContext后,这一系列的操作都被整合到ApplicationContext的refresh方法中了。
@Test
public void testXML() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
applicationContext.registerShutdownHook();
UserService userService = applicationContext.getBean("userService", UserService.class);
System.out.println("测试结果:" + userService);
}
2. ApplicationContext的结构
大概这个样子
继承:ApplicationContext的一系列继承
组合:组合DefaultListableBeanFactory,主要用于委托接口中的功能。
整体就是refresh中的九个步骤
public void refresh() throws BeansException {
// 1. 加载BeanDefinition
refreshBeanFactory();
// 2. 获取beanFactory
ConfigurableListableBeanFactory factory = getBeanFactory();
// 3. 添加ApplicationContextAwareProcessor
factory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 4. 调用factoryPostProcessor
invokeBeanFactoryPostProcessor(factory);
// 5. 注册beanPostProcessor
registerBeanPostProcessor(factory);
// 6. 初始化事件
initApplicationEventMulticaster();
// 7. 注册listener
registerListener();
// 8. 这里会把所有的bean全部调用一次getBean方法
factory.preInstantiateSingletons();
// 9. finish
finishRefresh();
}
一些具体的实现
3.1 FactoryBean**FactoryBean**和**BeanFactory**的区别
BeanFactory是用来生成Bean和管理Bean的
而FactoryBean也属于Bean
如果容器getBean时发现是一个FactoryBean,就会去调用FactoryBean的getObject方法。
这样做有什么用途呢?
一个实际的案例就是Mybatis中,利用FactoryBean为service层的对象自动提供代理
在调用service的createBean时,去get具体的ORM对象时,会调用他的getObject方法。
和XmlBeanDefinitionReader组合,从xml中解析bean对象
XmlBeanDefinitionReader和ResourceLoader组合,加载流并且获取流
ResourceLoader的类结构

这部分通过定义了一个ApplicationContextMulticaster对象用来管理和通知listener
如果有event发生
通过application.publishEvent方式
那么就会通过ApplicationContextMulticaster对象通知所有的listener,listener检查是不是自己的event
主要通过检查泛型类是否和event一样
然后调用listener的响应的方法。
Aware的作用是给bean提供了一个可以反向利用Spring framework中组件的机会,他会在getBean中的createBean方法中判断bean需要哪一个类型的aware,然后调用相应的set方法,将容器中的组件set进去,大概像是这个样子(反射)
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationStartupAware) {
((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
4. 总结
4.1 设计模式
- 经典的模板方法模式。(严格意义上来说不算是模板方法模式,只是把各个功能分层,不同的实现放到了不同的抽象类中。
- 委托模式。ApplicationContext也继承自BeanFactory,但他的关于这部分的方法实现委托给了同样实现了该相关接口的DefaultListableBeanFactory。但是ApplicationContext实现ListableBeanFactory二层子接口,但是DefaultListableBeanFactory实现了三个二层子接口,为什么还能委托? 我感觉到就是这种模式的精妙之处,只把自己需要的部分委托出去。(有深意,注意理解)。
- 适配器模式。DisposableBeanAdapter(这个的作用是,将disposableBean和destoryMethod中的统一到一个adpater中,然后容器统一去处理这个adpater
- 观察者模式。事件处理(使用经典的观察者模式)multicaster相当于subject,listener相当于订阅者,至于两者的绑定是在容器中的refresh中进行的。(get所有type为applicationListener的bean,然后绑定)
慢慢体会到,接口这样分层的目的,可以起到控制权限的作用。



