一、IOC和DI 概述
IOC(控制反转):反转资源的获取方向。Spring 容器管理对象的创建、设置和销毁,并主动将资源推送给它所管理的组件,组件只需要选择一种合适的方式来接收资源。相比于传统的组件主动向容器发起查询资源的请求的资源查找方式,被动的接收资源的形式称为反转控制。
DI(依赖注入):依赖出入是IOC的另一种描述,组件接收来自容器的资源注入。
二、Bean配置
1、bean的使用
applicationContext.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="hello" class="com.lys.applictionContext.Hello"></bean>
<bean id="person" class="com.lys.applictionContext.Person"></bean>
<bean id="car" class="com.lys.applictionContext.Car"></bean>
</beans>
applicationContext.xml 中定义了三个bean ,通过Id唯一标识。
public static void main(String[] args) {
//获取容器
ApplicationContext cx = new ClassPathXmlApplicationContext("applicationContext.xml");
//按名称从容器获取bean
Hello hello = (Hello) cx.getBean("hello");
hello.say();
//按类型获取bean
Hello hello1 = (Hello) cx.getBean(Hello.class);
hello1.say();
}
- 通过加载applicationContext.xml,创建容器
- 通过Id获取容器中的bean
- 通过类型获取bean
注意:通过类型获取bean,只能在容器中各个bean的类型均不相同时使用,在下面情况下不可用,因为有两个bean符合条件,spring容器无法确定返回那个bean:
<?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="car" class="com.lys.applictionContext.Car"></bean>
<bean id="car"1 class="com.lys.applictionContext.Car"></bean>
</beans>
2、依赖注入方式
- 属性注入
public class Person {
private String name;
private String city;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
<?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="person" class="com.lys.applictionContext.Person">
<property name="name" value="小明"></property>
<property name="city" value="广州"></property>
<property name="age" value="25"></property>
</bean>
</beans>
利用bean的属性property 给POJO的属性赋值,需要特别注意POJO的成员变量名称并不是配置文件里的属性名称,而set和get方法的后缀名才是属性名称,如下图所示。虽然现在成员变量一般也称作属性。
- 构造器注入
public class Person {
private String name;
private String city;
private int age;
public Person() {
}
public Person(String name, String city, int age) {
this.name = name;
this.city = city;
this.age = age;
}
}
<bean id="person" class="com.lys.applictionContext.Person">
<!--对应构造器参数的顺序-->
<constructor-arg value="小明"/>
<constructor-arg value="广州"/>
<constructor-arg value="20"/>
</bean>
bean中的参数顺序应与POJO中的构造器参数顺序一致;若果不一致,则需指明阐述位置,如下所示:
<bean id="person" class="com.lys.applictionContext.Person">
<!--通过index 指定参数顺序-->
<constructor-arg index="1" value="广州" type="java.lang.String"/>
<constructor-arg index="2" value="20" type="java.lang.Integer"/>
<constructor-arg index="0" value="小明" type="java.lang.String"/>
</bean>
index 属性指定参数位置,index="0" 表明是构造器的第一个参数。另外,type指明了构造器的参数类型,在构造器重载的情况下,可以避免初始化错误;
public class Person {
private String name;
private String city;
private int age;
private double money;
public Person() {
}
public Person(String name, String city, double money) {
this.name = name;
this.city = city;
this.money= money;
}
public Person(String name, String city, int age) {
this.name = name;
this.city = city;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", city='" + city + '\'' +
", age=" + age +
", money=" + money +
'}';
}
}
<bean id="person" class="com.lys.applictionContext.Person">
<!--通过index 指定参数顺序-->
<constructor-arg index="1" value="广州" />
<constructor-arg index="2" value="25000000"/>
<constructor-arg index="0" value="小明"/>
</bean>
当不指定第二个参数的类型时,25000000将注入到属性age,不合常理;
指定参数类型后,结果如下:
总结:
- IOC:将对象的创建和管理工作交给spring,当需要对象时,spring主动通过属性注入或构造器注入的方式提供给组件。
- 如果容器中存在多个同类型的bean,那么不能按类型获取bean(注入bean),需要通过id名称唯一指定bean.
- 利用构造器注入时,bean中参数顺序和构造器参数顺序一致,则不需要通过index指定顺序;如果存在构造器重载,注意检查是否需要在bean中指定参数类型。