Q:说说@Autowired
和@Resource
的区别
@Resource
:该注解会优先通过bean的名称而不是类型来寻找依赖。如果你趋向于使用bean名称来配置基于注解驱动的注入,请尽量不要使用@Autowired,虽然可通过@Qualifier来指定bean的名称,你应该尝试使用@Resource。@Autowired
:@Autowired应用于属性、构造函数以及多参函数,配合@Qualifier一起使用可以定位bean;而@Resource只支持属性、单参数的属性setter方法。所以如果你的配置目标是构造函数或者多参方法,请使用@Autowired和@Qualifier。
Q:IoC容器的Bean生命周期
Q:介绍下IoC容器初始化流程
IoC容器的初始化过程,主要就体现在AbstractApplicationContext
的refresh()
方法中,如下:
Q:说说IoC容器的架构设计
以FileSystemXmlApplicationContext为例子说明:
-
BeanFactory
:定义了基本的IoC容器规范,包含containsBean, getBean, getBeanProvider, isPrototype, isSingleton等基本的IoC容器方法;AutowireCapableBeanFactory
:在BeanFactory
基础上实现了对存在实例的管理.可以使用这个接口集成其它框架,捆绑并填充并不由Spring管理生命周期并已存在的实例.像集成WebWork的Actions 和Tapestry Page就很实用;一般应用开发者不会使用这个接口,所以像ApplicationContext
这样的外观实现类不会实现这个接口,如果真想使用,可以通过ApplicationContext
的getAutowireCapableBeanFactory
接口获取;HierarchicalBeanFactory
:提供父容器的访问功能;至于父容器的设置,需要ConfigurableBeanFactory的setParentBeanFactory;ListableBeanFactory
:提供容器中bean迭代的功能,不再需要一个个bean地查找;ConfigurableBeanFactory
:同时继承了HierarchicalBeanFactory 和 SingletonBeanRegistry 这两个接口,BeanFactory的配置接口,被大部分BeanFactory实现,包含了配置BeanFactory的各种工具方法;ConfigurableListableBeanFactory
:接口的集大成者,同时继承了3个接口,ListableBeanFactory、AutowireCapableBeanFactory 和 ConfigurableBeanFactory,同时提供了解析和修改bean definitions的方法,以及预实例化singletons;DefaultListableBeanFactory
:作为一个默认的功能完整的IoC容器来使用,是接口ConfigurableListableBeanFactory和BeanDefinitionRegistry的默认实现。工厂中的Bean都是基于元数据定义的 bean 和通过post-processors扩展的bean;
-
Resource
是Spring用来封装I/O操作的类; -
ApplicationContext
是一个高级形态意义的IoC容器:- 支持不同的信息源:继承接口Messagesource;
- 访问资源:继承接口ResourceLoader;
- 支持应用事件:继承接口ApplicationEventPublisher;
- 在ApplicationContext中提供附加功能;
-
ConfigurableApplicationContext
:一个SPI接口,大部分ApplicationContext都实现了这个接口,提供了配置ApplicationContext的方法。其中容器启动过程调用的refresh方法就在这个接口定义; -
AbstractApplicationContext
:其中refresh()
方法的具体实现在这个抽象类中,这个refresh()
方法会涉及到IoC容器启动的一系列负载操作,针对不同的容器实现,这些操作都是类似的。 -
AbstractXmlApplicationContext
:在AbstractXmlApplicationContext
中做的操作就是对applicationContext.xml的解析操作,主要是由两个函数loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
和loadBeanDefinitions(XmlBeanDefinitionReader reader)
中实现; -
FileSystemXmlApplicationContext
:指定了获取Resource的方式,通过以下方法:1
2
3
4
5
6
7
protected Resource getResourceByPath(String path) {
if (path.startsWith("/")) {
path = path.substring(1);
}
return new FileSystemResource(path);
}可以发现,这里依赖于
FileSystemResource
这个类。
Q:Spring IoC容器中提现了哪些设计模式,或者软件设计思想
1、实例化Bean使用了策略模式
与传统的策略模式不太一样,SimpleInstantiationStrategy.instantiate()为实例化入口,如果是接口实现,则调用子类的实例化方法CglibSubclassingInstantiationStrategy.instantiateWithMethodInjection
2、接口隔离原则
客户端不应该依赖它不需要的接口;类间的依赖关系应该建立在最小的接口上
清晰地定义了如下的体系:
根接口BeanFactory(基础容器)
第二层: 第三方集成 AutowireCapableBeanFactory ,继承体系 HierarchicalBeanFactory ,遍历bean ListableBeanFactory
第三层: 配置功能 ConfigurableBeanFactory
第四层: 配置+迭代 ConfigurableListableBeanFactory
3、事件驱动架构
IoC架构设计图里面,我们重点关注ApplicationEventPublisher
以及事件发布机制相关的类:
这里采用了事件驱动架构。关于具体的时间驱动模型以及Spring的事件驱动实现原理参考:事件驱动模型与观察者模式
4、模板方法模式
Spring的容器启动流程涉及的refresh方法使用了模板方法模式。
References
Spring源码解析 - BeanFactory接口体系解读
Spring源码学习–AutowireCapableBeanFactory接口
Spring源码学习–HierarchicalBeanFactory接口
Spring源码学习–ListableBeanFactory接口
Spring源码学习–ConfigurableBeanFactory接口
Spring源码学习–AbstractXmlApplicationContext抽象类
Spring IoC:invokeBeanFactoryPostProcessors 详解
spring4.2.9 java项目环境下ioc源码分析 (十三)——refresh之initApplicationEventMulticaster方法