容器的实现

Spring的IoC容器就是IoC思想的一个落地的产品实现。IoC容器中管理的组件也叫bean。创建bean之前,首先需要创建IoC容器。Spring提供了IoC容器的两种实现方式:

  1. 这是IoC容器的基本实现,是Spring内部使用的接口。面向Spring本身,不提供给开发人员使用

  2. ApplicationContext

    BeanFactory的子接口,提供了更多高级特性。面向Spring的使用者,几乎所有场合都使用ApplicationContext而不是底层的BeanFactory

  3. ApplicationContext的实现主要类

BeanFactory

使用BeanFactory

1
2
3
4
5
6
7
8
9
10
11
public class DiTest {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);

reader.loadBeanDefinitions("factorybean.xml");

UserService userService = (UserService) beanFactory.getBean("userService");
}
}
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="com.wereash.iocbyxml.beanfactorytest.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>

<bean id="userDao" class="com.wereash.iocbyxml.beanfactorytest.dao.impl.UserDaoImpl"></bean>
</beans>

  • bean id就是会自动转化为beanname

BeanFactory与ApplicationContext的关系

  • BeanFactory是Spring的早期接口,称为Spring的Bean工厂,ApplicationContext是后期更高级接口,称之为Spring 容器;
  • ApplicationContext在BeanFactory基础上对功能进行了扩展,例如: 监听功能、国际化功能等。BeanFactory的API更偏向底层,ApplicationContext的API大多数是对这些底层API的封装
  • Bean创建的主要逻辑和功能都被封装在BeanFactorv中,ApplicationContext不仅继承了BeanFactory,而且ApplicationContext内部还维护着BeanFactory的引用,所以,ApplicationContext与BeanFactory既有继承关系,又有融合关系(内部还维护了一个beanfactory引用)
  • Bean的初始化时机不同,原始BeanFactory是在首次调用getBean时才进行Bean的创建,而ApplicationContext是配置文件加载,容器一创建就将Bean都实例化并初始化好。

ApplicationContextAware

实现ApplicationContextAware接口之后,系统启动时就可以自动给我们的服务注入applicationContext对象(自动调用了接口中的setApplicationContext方法),我们就可以获取到ApplicationContext里的所有信息了。

注意:实现ApplicationContextAware接口的类需要交给spring管理,使用@Component或者在配置文件声明bean

我们获取ApplicationContext,一般是用来获取bean的,AoolicationContext有一个getBean方法,此方法继承自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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class ApplicationContextHolder implements ApplicationContextAware {

private static ApplicationContext CONTEXT;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ApplicationContextHolder.CONTEXT = applicationContext;
}

/**
* Get ioc container bean by type.
*/
public static <T> T getBean(Class<T> clazz) {
return CONTEXT.getBean(clazz);
}

/**
* Get ioc container bean by name.
*/
public static Object getBean(String name) {
return CONTEXT.getBean(name);
}

/**
* Get ioc container bean by name and type.
*/
public static <T> T getBean(String name, Class<T> clazz) {
return CONTEXT.getBean(name, clazz);
}

/**
* Get a set of ioc container beans by type.
*/
public static <T> Map<String, T> getBeansOfType(Class<T> clazz) {
return CONTEXT.getBeansOfType(clazz);
}

/**
* Find whether the bean has annotations.
*/
public static <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) {
return CONTEXT.findAnnotationOnBean(beanName, annotationType);
}

/**
* Get application context.
*/
public static ApplicationContext getInstance() {
return CONTEXT;
}
}