IOC与DI:
IOC(inversion of control):其思想是反转资源获取的方向。传统的资源查找方式要求组件向容器发起请求查找资源。作为回应,容器适时的返回资源。
而应用了IOC之后,则是容器主动地将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接收资源。这种方式也被称为查找的被动形式。
DI(dependency injection):IOC的另一种表述形式,即组件以一些预先定义好的方式(例如setter方法)接受来自如容器的资源注入。相对于IOC而言,这种表述更直接。
Spring容器:
在Spring IOC容器读取Bean配置创建Bean实例之前,必须对它进行实例化。只有在容器实例化后,才可以从IOC容器里获取Bean实例并使用。
Spring提供了两种类型的IOC容器实现。
-BeanFactory:IOC容器的基本实现
-ApplicationContext:提供了更多的高级特性。是BeanFactory的子接口
-BeanFactory是Spring框架的基础设施,面向Spring本身;ApplicationContext面向使用Spring框架的开发者,几乎所有的应用场合都直接使用ApplicationContext而非底层的BeanFactory
-无论使用何种方式,配置文件是相同的。
ApplicationContext的继承结构图
ApplicationContext的主要实现类:
-ClassPathXmlApplicationContext:从类路径下加载配置文件
-FileSystemXmlApplicationContext:从文件系统中加载配置文件
ConfigurableApplicationContext扩展于ApplicationContext,新增两个主要方法:refresh()和close(),让ApplicationContext具有启动、刷新和关闭上下文的能力。
ApplicationContext在初始化上下文时就实例化所有单例的Bean
WebApplicationContext是专门为WEB应用而准备的,它允许从相对于WEB根目录的路径中完成初始化工作。
属性的注入方法:
Spring支持3种依赖注入的方式
-属性注入
-构造器注入
-工厂方法注入(很少使用,不推荐)
属性注入即通过setter方法注入bean的属性值或依赖的对象
属性注入使用<property>元素,使用name属性指定bean的属性名称,value属性或<value>节点指定属性值
属性注入是实际应用中最常用的注入方式
1 <!-- 配置bean 2 class:bean的全类名,通过反射的方式在IOC容器中创建Bean,所以要求Bean中必须有无参数的构造器 3 id:标识容器中的bean,id唯一。 4 --> 5 <bean id="helloSpring" class="com.yl.HelloSpring"> 6 <property name="name" value="Spring"></property> 7 </bean>
构造方法注入
通过构造方法注入bean的属性值或依赖的对象,它保证了bean实例在实例化后就可以使用
构造器注入在<constructor-arg>元素里声明属性
1 <!-- 使用构造器注入属性值可以指定参数的位置和参数的类型,以区分重载的构造器 --> 2 <bean id="car" class="com.yl.Car"> 3 <constructor-arg value="Audi" index="0"></constructor-arg> 4 <constructor-arg value="Shanghai" index="1"></constructor-arg> 5 <constructor-arg value="300000" type="double"></constructor-arg> 6 </bean> 7 8 <bean id="car2" class="com.yl.Car"> 9 <constructor-arg value="BMW" type="java.lang.String"></constructor-arg> 10 <constructor-arg value="Shanghai" type="java.lang.String"></constructor-arg> 11 <constructor-arg value="200" type="int"></constructor-arg> 12 </bean>
配置文件中使用到的Car类的代码:
1 package com.yl; 2 3 public class Car { 4 5 private String brand; 6 private String origin; 7 private double price; 8 private int speed; 9 public Car(String brand, String origin, double price) { 10 super(); 11 this.brand = brand; 12 this.origin = origin; 13 this.price = price; 14 } 15 public Car(String brand, String origin, int speed) { 16 super(); 17 this.brand = brand; 18 this.origin = origin; 19 this.speed = speed; 20 } 21 @Override 22 public String toString() { 23 return "Car [brand=" + brand + ", origin=" + origin + ", price=" 24 + price + ", speed=" + speed + "]"; 25 } 26 27 28 }
测试代码:
1 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 2 3 Car car = (Car)ctx.getBean("car"); 4 System.out.println(car); 5 6 car = (Car)ctx.getBean("car2"); 7 System.out.println(car);
输出:
Car [brand=Audi, origin=Shanghai, price=300000.0, speed=0]
Car [brand=BMW, origin=Shanghai, price=0.0, speed=200]