@[TOC]
创建容器
前文案例中我们创建ApplicationContext
的方式为:
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
这种方式翻译为:==类路径下的XML配置文件==
除了上面这种方式,Spring还提供了另外一种创建方式为:
ApplicationContext ctx = new FileSystemXmlApplicationContext("applicationContext.xml");
这种方式翻译为:==文件系统下的XML配置文件==
使用这种方式,运行,会出现如下错误:
从错误信息中能发现,这种方式是从项目路径下开始查找applicationContext.xml
配置文件的,所以需要将其修改为:
ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\workspace\\spring\\spring_10_container\\src\\main\\resources\\applicationContext.xml");
这种方式虽能实现,但是当项目的位置发生变化后,代码也需要跟着改,耦合度较高,不推荐使用。
bean的三种获取方式
方式一,就是目前案例中获取的方式:
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
这种方式存在的问题是每次获取的时候都需要进行类型转换,有没有更简单的方式呢?
方式二:
BookDao bookDao = ctx.getBean("bookDao",BookDao.class);
这种方式可以解决类型强转问题,但是参数又多加了一个,相对来说没有简化多少。
方式三:
BookDao bookDao = ctx.getBean(BookDao.class);
这种方式就类似我们之前所学习依赖注入中的按类型注入。必须要确保IOC容器中该类型对应的bean对象只能有一个。
容器类层次结构
我们在初始化容器的时候最经常用的就是ApplicationContext
接口了,我们来查看一下他的类结构:
我们可以发现有一个ConfigurableApplicationContext
接口继承了它,这也就是说ApplicationContext
接口提供了基础功能,而他的子接口ConfigurableApplicationContext
对它进行了一个功能上的追加。
此时我们还有一个疑问ApplicationContext
接口上面还有没有接口呢?
我们打开源码发现它继承了很多:
EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver。
然后我们通过层层寻找发现ApplicationContext
的顶层接口可以通过ListableBeanFactory一层层往上找到,它就是BeanFactory
接口
在Spring1.0的时候是没有ApplicationContext
接口的,但当时存在BeanFactory
接口。也就是说使用BeanFactory
接口也能创建我们的IOC容器。但是BeanFactory
接口也存在它的一些局限性,所以后期在它的基础之上发展出了ApplicationContext
接口,并且通过若干子接口的扩张达到了一个最佳的状态。总的来说现在ApplicationContext
接口提供的功能要比BeanFactory
接口多得多。
完整的类层次结构:
使用指导:
BeanFactory的使用
这一小节的内容我们了解即可。
使用BeanFactory来创建IOC容器的具体实现方式为:
public class AppForBeanFactory {
public static void main(String[] args) {
Resource resources = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(resources);
BookDao bookDao = bf.getBean(BookDao.class);
bookDao.save();
}
}
为了更好的看出BeanFactory
和ApplicationContext
之间的区别,在BookDaoImpl添加如下构造函数:
public class BookDaoImpl implements BookDao {
public BookDaoImpl() {
System.out.println("constructor");
}
public void save() {
System.out.println("book dao save ..." );
}
}
如果不去获取bean对象,打印会发现:
- BeanFactory是延迟加载,只有在获取bean对象的时候才会去创建
- ApplicationContext是立即加载,容器加载的时候就会创建bean对象
ApplicationContext要想成为延迟加载,只需要按照如下方式进行配置
<?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="bookDao" class="com.itheima.dao.impl.BookDaoImpl" lazy-init="true"/> </beans>
核心容器总结
容器相关
- BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载
- ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载
- ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能
ApplicationContext接口常用初始化类
- ==ClassPathXmlApplicationContext(常用)==
- FileSystemXmlApplicationContext
bean相关
其实整个配置中最常用的就两个属性==id==和==class==。
scope、init-method、destroy-method这三个属性后面注解开发的时候还会用到