所谓的ioc容器,以我目前狭义的理解,即指ApplicationContext类,在spring全家桶中也被称为上下文。
我们一直在说,spring是一个解耦合的框架,spring通过xml或注解依赖注入相关的bean,不需要手动的new对象。但究竟是怎么注入的还是没有清晰的概念。这篇博客在考察相关资料之后完成。
引入问题:
想一想,在我们一开始学习spring的时候,我们写了几个bean,然后在xml中做配置,然后怎么测试依赖注入的呢?
是像springboot中那样直接@Autowired吗?
如果还有印象,那么大多数人的起点应该是这段代码:
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
ClassName cn = (ClassName)ac.getBean("beanName");
通过ClassPathXmlApplicationContext来加载我们写好的spring配置文件,用ApplicationContext来接收,随后使用getBean方法来得到我们在xml中配置好的bean。
而ApplicationContext就是ioc容器,所有的bean都将被它所管理,支配。
深入研究
Spring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口。他们都可代表Spring容器,Spring容器是生成Bean实例的工厂,并且管理容器中的Bean。
Bean是Spring管理的基本单位,在基于Spring的Java EE应用中,所有的组件都被当成Bean处理,除了自定义的javabean,还包括数据源、事务管理器等。在Spring中,Bean的是一个非常广义的概念,任何的Java对象、Java组件都被当成Bean处理。
而且应用中的所有组件,都处于Spring的管理下,都被Spring以Bean的方式管理,Spring负责创建Bean实例,并管理他们的生命周期。Bean在Spring容器中运行,无须感受Spring容器的存在,一样可以接受Spring的依赖注入,包括Bean属性的注入,协作者的注入、依赖关系的注入等。
Spring容器负责创建Bean实例,所以需要知道每个Bean的实现类,Java程序面向接口编程,无须关心Bean实例的实现类;但是Spring容器必须能够精确知道每个Bean实例的实现类,因此Spring配置文件必须精确配置Bean实例的实现类。
基本的Spring容器
Spring容器最基本的接口就是BeanFactory。BeanFactory负责配置、创建、管理Bean,他有一个子接口:ApplicationContext,因此也称之为Spring上下文。Spring容器负责管理Bean与Bean之间的依赖关系。
BeanFactory接口包含以下几个基本方法:
Ø Boolean containBean(String name):判断Spring容器是否包含id为name的Bean实例。
Ø
Ø Object getBean(String name):返回Sprin容器中id为name的Bean实例。
Ø
Ø Class > getType(String name):返回容器中指定Bean实例的类型。
调用者只需使用getBean()方法即可获得指定Bean的引用,无须关心Bean的实例化过程。即Bean实例的创建过程完全透明。
在使用BeanFactory接口时,我们一般都是使用这个实现类:org.springframework.beans.factory.xml.XmlBeanFactory。然而ApplicationContext作为BeanFactory的子接口,使用它作为Spring容器会更加方便。它的实现类有:FileSystemXmlApplicationContext、ClassPathXmlApplicationContext、AnnotationConfigApplicationContext。
创建Spring容器实例时,必须提供Spring容器管理的Bean的详细配置信息。Spring的配置信息通常采用xml配置文件来设置,因此,创建BeanFactory实例时,应该提供XML配置文件作为参数。
XML配置文件通常使用Resource对象传入。Resource接口是Spring提供的资源访问接口,通过使用该接口,Spring能够以简单、透明的方式访问磁盘、类路径以及网络上的资源。
FileSystemXmlApplicationContext:以基于文件系统的XML配置文件创建ApplicationContext实例。
ClassPathXmlApplicationContext:以类加载路径下的XML配置文件创建的ApplicationContext实例。
//搜索CLASSPATH路径,以classpath路径下的bean.xml、service.xml文件创建applicationContext
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"bean.xml","service.xml"});
//以指定路径下的bean.xml、service.xml文件创建applicationContext
ApplicationContext ctx1 = new FileSystemXmlApplicationContext(new String[]{"bean.xml","service.xml"});
ps:
在Spring中我们可以使用Spring容器中getBean()方法来获取Spring容器中的Bean实例。在这样的访问模式下,程序中总是持有Spring容器的引用。(即我们想得到ioc中的bean至少要在程序中创建一个applicationContext类)但是在实际的应用中,一般是采用像springmvc.xml中自动扫描包+@Autowired的方式来自动注入。
而到了springboot,由于xxx-autoconfigration类的存在,我们连springmvc.xml这种配置文件都省了,如果需要将某些类加入ioc容器,只需要加上相关注解,如@controller,@service,@bean等。
在使用的时候,也只需要@Autowired,对于使用者来说完全没有任何门槛。