搭建好源码阅读环境后,就可以慢慢走进Spring殿堂了。IOC是Inversion of Control的缩写,控制反转的意思。很多人可能都知道IOC是spring的核心,将对象的创建初始化等权限交由容器控制,从而减少对象之间的依赖。甚至听说过BeanFactory,知道BeanFactory是实现IOC机制的核心,但是具体如何实现,却不是十分清楚。下面我们来一步一步深入理解BeanFactory。
在spring工程应用中,一般用spring注解
来自动加载依赖对象,如下所示:
- @Autowired
- public class MerchantController {
- @Autowired
- private final MerchantService merchantService;
- }
注解
使得对象加载很方便,使得对象依赖间管理很容易。但是依据守恒定律,对象的加载、创建、初始化等步骤是不会减少的,这里使用简单了,那必然在别的地方执行了对象的加载、创建、初始化的过程。实际上这个加载、创建、初始化的过程是在Spring源码BeanFactory中完成的。
- @Autowired
首先看下BeanFactory源码,BeanFactory是一个祖宗级接口,定义了Bean Factory的各种基本方法。spring中各种具体bean工厂均是对BeanFactory接口的实现,如DefaultListableBeanFactory,SimpleJndiBeanFactory,StaticListableBeanFactory等。
作为一个接口,BeanFactory定义的方法非常简单,而且都是一些常用的方法模板,如:
,
- getBean()
,
- containsBean()
方法。BeanFactory接口如下:
- isSingleton()
- package org.springframework.beans.factory;
- import org.springframework.beans.BeansException;
- import org.springframework.core.ResolvableType;
- public interface BeanFactory {
- String FACTORY_BEAN_PREFIX = "&";
- Object getBean(String name) throws BeansException;
- < T > T getBean(String name, Class < T > requiredType) throws BeansException;
- < T > T getBean(Class < T > requiredType) throws BeansException;
- Object getBean(String name, Object...args) throws BeansException;
- < T > T getBean(Class < T > requiredType, Object...args) throws BeansException;
- boolean containsBean(String name);
- boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
- boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
- boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
- boolean isTypeMatch(String name, Class < ?>typeToMatch) throws NoSuchBeanDefinitionException;
- Class < ?>getType(String name) throws NoSuchBeanDefinitionException;
- String[] getAliases(String name);
- }
顾名思义,
方法是用来获取Bean工厂中存储的对象实例,根据
- getBean()
即可获得对应的对象,也即是配置文件(暂认为xml)中定义的
- name
。
- id
是用于判断该Bean工厂中是否含有
- containsBean
所对应的对象。
- name
是判断该
- isSingleton
所对应的Bean是否是共享的单例,如果true的话,当调用
- name
方法时便会返回该Bean。
- getBean()
由
方法,应该能够猜测出:Bean工厂是先将name-bean作为一个键值对存储在一个容器中,当调用
- getBean()
方法时,根据key值取出对应的bean值。实际上,spring中的确是这么做的。
- getBean()
根据UML类图关系,找到BeanFactory接口对应的默认实现类DefaultListableBeanFactory,如下图所示。
查看DefaultListableBeanFactory源码,发现:属性中beanDefinitionMap用于存储name-bean键值对,也即是存放Bean工厂实例化后的bean。截取部分源码如下:
- package org.springframework.beans.factory.support;
- @SuppressWarnings("serial") public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory,
- BeanDefinitionRegistry,
- Serializable {............
- /** Map of bean definition objects, keyed by bean name */
- private final Map < String,
- BeanDefinition > beanDefinitionMap = new ConcurrentHashMap < String,
- BeanDefinition > (256);...........
- }
从源码可以发现,存储键值对的容器是
,它是一个基于HashMap的高并发容器,具有很好的线程安全性。其存储的不是String-Object键值对,而是String-BeanDefinition键值对,也就是说创建的bean对象不是以Object类型存储的,而是Bean Definition类型存储。为什么是这样的呢?请听下回分解
- ConcurrentHashMap
来源: http://www.cnblogs.com/hthuang/p/7807844.html