IOC容器,有时候也称为依赖注入(DI)。通过对象自己定义的依赖项,在创建bean的时候,再把这些依赖项注入进来。这个过程,跟我们正常的设计是相反的,我们正常是在对象里new一个对象,是我们的程序控制管理对象,而在spring里,是通过容器来创建对象的,由容器来控制的。在基于spring的应用中,IOC容器基于配置元数据,实例化、配置、组装对象,并管理这些对象的整个生命周期。
配置元数据的读取,可以通过XML文件、注解等方式,可以用的上下文有ClassPathXmlApplicationContext、AnnotationConfigApplicationContext等。BeanFactory和ApplicationContext是比较常用的类,正常情况下,我们用ApplicationContext,ApplicationContext继承了BeanFactory,包含了BeanFactory的所有功能。
在基于spring的应用中,IOC容器管理的对象,称之为bean。每个应用是由多个bean组成的,bean之间的依赖关系由容器来管理。
元数据的配置,用来告诉Spring容器如何实例化、配置和组装应用程序中的对象。
XML配置文件时,用bean标签来配置元数据。注解下用@bean、@Configuration等来配置元数据。
配置文件daos.xml
<?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"> <!--id是bean的唯一标识,class是bean的全类名--> <bean id="orderDao" class="com.learn.ch1.OrderDao"/> </beans>
配置文件services.xml
<?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="orderService" class="com.learn.ch1.OrderService"/> </beans>
测试代码
@Test public void test() { //这边可以直接引入多个xml配置文件,也可以引入一个,然后在这个xml里用<import resource="XXX.xml"/>标签引入其他配置文件。 //XML用的ApplicationContext是ClassPathXmlApplicationContext ApplicationContext app = new ClassPathXmlApplicationContext("services.xml","daos.xml"); String[] names = app.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } }
另外两个java类就不写了,运行结果如下:
MyConfig
@Configuration public class MyConfig { @Bean public OrderDao orderDao() { return new OrderDao(); } @Bean public OrderService orderService() { return new OrderService(); } }
测试代码
@Test public void test() { //注解下用的ApplicationContext是AnnotationConfigApplicationContext ApplicationContext app = new AnnotationConfigApplicationContext(MyConfig.class); String[] names = app.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } }
运行结果如下:
从上面两个例子可以看出,注解下的配置,更短更简洁,但不是说注解的方式更好。
XML也是有优点的: