
1. 为什么要有ApplicationContext详情请见 https://github.com/StrongChenYu/Tiny-Spring
ApplicationContext主要是为了将以下几个步骤(当然源spring中可能有更多)整合起来,放到一个容器中,提供生命周期管理。
如果不经过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 设计模式
慢慢体会到,接口这样分层的目的,可以起到控制权限的作用。