记忆、淡忘

Spring IoC容器

Spring的IoC容器就是一个实现了BeanFactory接口的可实例化类。事实上,Spring提供了两种不同的容器:一种是最基本的BeanFactory,另一种是扩展的ApplicationContext。

UML

一、 BeanFactory

BeanFactory接口定义了Spring IoC容器的基本功能规范,是Spring IoC容器所应遵守的最底层和最基本的编程规范

源码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
* BeanFactory是Spring容器的根接口,提供了 IOC 容器最基本的功能。
* BeanFactory只是一个接口,没有具体的实现,但是它的实现类如ListableBeanFactory、
* ConfigurableBeanFactory都实现了某些功能。
*
* BeanFactory的作用是持有一定数量的Bean Definition,每一个都有一个独有的String名字。
* BeanFactory可以返回单例或多例的对象,取决于Bean定义文件。
*
* 通过setters,constructors进行依赖注入更好,其实这也是常用的方法。
* BeanFactory加载的 bean definitions 配置源(如XML文档)的方式,并使用
* org.springframework.beans 包来配置beans.
*
* 与ListableBeanFactory中的方法相比,在此接口中的所有操作还将检查父母工厂是否是
* HierarchicalBeanFactory。在这个工厂如果没有找到一个bean实例,直接父工厂将被调用。
* 在这个工厂中的bean实例如果与父工厂中的名称相同会被重写。
*/
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
/**
* 这个方法是BeanFactory的主要方法,通过指定名字可以取得IOC容器中相应的Bean对象
* 这种方法使得Spring BeanFactory代替单例或原型设计模式来获取Bean对象
*/
Object getBean(String name) throws BeansException;
/**
* 也是获取Bean对象的方法,但是增加了Class类型的安全验证机制
* 如果类型不符,则跑出BeanNotOfRequiredTypeException异常
*/
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
/**
* 通过Bean类型获取bean实例
*/
<T> T getBean(Class<T> requiredType) throws BeansException;
/**
* 该方法重载了getBean(String name)方法,为构造函数指定对应的参数创建一个原型(prototype)Bean。
*/
Object getBean(String name, Object... args) throws BeansException;
/**
*
*/
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
/**
* 判断是否含有指定名字的bean对象
*/
boolean containsBean(String name);
/**
*判断指定名称的bean对象是否是单例,如果是,则永远返回同一个对象
* 可以在 BeanDefinition中设置
*/
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
/**
* 判断Bean是不是prototype的bean,是的话 返回独立的实例
*/
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
/**
*
*/
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
/**
* 判断指定名称的bean对象的Class类型是否是特定的Class类型。
*/
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
/**
* 获取指定名称bean对象的Class类型
*/
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
/**
*查询指定了名字的bean的所有别名,这些别名都是在BeanDefinition中定义的
*/
String[] getAliases(String name);
}

二、 XmlBeanFactory

1、XmlBeanFactory只提供最基本的IoC容器功能,它主要读取以XML形式定义的BeanDefinition。
2、XmlBeanFactory在DefaultListableBeanFactory的基础上扩展了xml读取的功能。

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class XmlBeanFactory extends DefaultListableBeanFactory {
///读取XML形式的BeanDefinition
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
/**
* 用给定的资源,创建一个新的XmlBeanFactory
* BeanDefinition的信息来源以Resource类传递
*/
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);//从XML文件中加载bean 定义
}
}

使用

1
2
3
4
5
ClassPathResource classPath = new ClassPathResource("applicationContext.xml");
XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(classPath);
User user= xmlBeanFactory.getBean(User.class);
System.out.print("---------"+user.getUser_name());

小结

使用IoC容器的步骤:
1、创建IoC配置文件抽象资源
2、创建一个BeanFactory
3、创建一个载入BeanDefinition的读取器
4、从定义好的资源未知读入配置信息

三、ApplicationContext

ApplicationContext是一个高级形态的IoC的容器,在BeanFactory的基础上进行了功能扩展。

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
/**
*获取ApplicationContext的id
*/
String getId();
/**
* 返回这个上下文所属的应用的名称
*/
String getApplicationName();
/**
* 获取ApplicationContext的displayName
*/
String getDisplayName();
/**
* 获取ApplicationContext第一次加载的时间戳
*/
long getStartupDate();
/**
* 获取ApplicationContext容器的父容器
*/
ApplicationContext getParent();
/**
* 取自动装配功能的BeanFactory
*/
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

扩展的特性

  • 支持不同的信息源。ApplicationContext 扩展了MessageSource接口,可以支持国际化配置。

  • 访问资源。AbstractApplicationContext是DefaultResourceLoader的子类。

  • 支持应用事件。pplicationContext继承了ApplicationEventPublisher接口,在程序上下文中引入了事件机制,这些事件和Bean生命周期的结合为Bean的过来提供了便利。