BeanFactory接口中定义了获取Bean的若干方法,而这些方法分别由不同的抽象类实现,我们知道在Java中抽象类实现接口的时候不是一定要实现接口中的每个方法的,Spring就是巧妙地利用了这点来设计它的架构。下面我们来逐一看这些方法的作用以及分别是由哪些类来实现的。
getBean方法
1 | Object getBean(String name) throws BeansException; |
从方法名就可以看出,用户可以传入Bean的名称获取到对应的Bean实例,这个实例可以是单例也可以是原型的,如果是单例就返回引用,如果是原型那么每次都返回不一样的实例,这个方法的api文档中有一句话说的比较好:
This method allows a Spring BeanFactory to be used as a replacement for the Singleton or Prototype design pattern.
该方法使得Spring中的BeanFactory成功应用了单例或者原型设计模式。文档中还提到了一点:
Translates aliases back to the corresponding canonical bean name
这句话代表如果传入的name是别名,那么会根据它对应的真正的bean名称去查找bean实例,就像Vlad Mihalcea在Why I like Spring bean aliasing中所说的那样,如果根据别名查找,那么实际会依据别名背后真正的bean名称去查找,那么原来如果存在跟这个别名相同的bean名称将被忽略,这种方法在需要切换数据源测试的时候非常有用,因为你只要改配置就好了。可以简单通过下面的截图源码了解下:
核心部分就是通过循环遍历aliasMap集合查找是否有该参数对应的别名Key,如果有那么再按照名称尝试作为别名Key去查找
这个方法最后还提到了一点:
Will ask the parent factory if the bean cannot be found in this factory instance
也就是说在当前bean容器中找不到的话还会去父容器中去查找。
这个getBean方法还有个重载的方法,对比上面就多传入了一个requiredType参数,方法签名如下:
1 | <T> T getBean(String name, Class<T> requiredType) throws BeansException; |
这个方法就强大多了,除了拥有上面的方法具备的功能之外,首先它支持了泛型,也就是返回类型不用再强制转换了。从它的api文档描述就可以看出:
Behaves the same as {@link #getBean(String)}, but provides a measure of type safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the required type. This means that ClassCastException can’t be thrown on casting the result correctly, as can happen with {@link #getBean(String)}.
也就是提供了类型安全的保障,Java的ClassCastException就不可能抛出了,getBean(String)对返回结果强制转换的时候有可能会遇到这个异常。那Spring是怎么做到这点的呢?
也就是通过Java中Class类的isInstance方法判断
另外api文档也提到了如下:
requiredType type the bean must match; can be an interface or superclass
参数requiredType可以是接口或者父类型,这个也是比较人性化的功能吧。
本文还会持续更新。。。