定义
- Inversion of Control:控制反转,是一个理论,概念,思想。
- 描述:把对象的创建、赋值、管理工作都交给代码之外的容器实现。
- 目的:减少对代码的改动,也能实现不同的功能。实现解耦。
DI
- Dependency Injection:依赖注入。
- DI是IoC的技术实现。
- spring是使用了的DI实现了IoC的功能,spring底层创建对象,使用的是反射机制。
基于XML的DI
注入分类
set注入(掌握)
- spring调用类的set方法,在set方法可以实现属性的赋值。80%左右都是使用set注入
- 所用标签:
<property name="xxx" value="xxx" />
简单类型的set注入
<bean id="xx" class="类全限定名">
<property name="属性名字" value="此属性的值" />
<!-- 一个property只能给一个属性赋值 -->
<property .....>
</bean>
- Tips:XML中属性名字在类中必须有对应的方法,可以没有对应的属性
- 例如:
–XML<bean id="student" class="com.wuuuula.Student">
<property name="name" value="张三"/>
<property name="age" value="22"/>
</bean>
–Student.javapackage com.wuuuula
public class Student{
private String name;
public void setName(String name){
this.name = name;
System.our.println("setName="+name);
}
public void setAge(Integer age){
System.our.println("setAge="+age);
}
}
引用类型的set注入
<bean id="xxx" class="类全限定名">
<property name="属性名称" ref="bean的id(对象的名称)" />
</bean>
构造注入(理解)
- spring调用类的有参构造方法,创建对象。在构造方法中完成赋值
- 所用标签:(推荐使用name)
<constructor-arg name="xxx" value="xxx" /><!-- 根据属性名称赋值 -->
<constructor-arg index="xxx" value="xxx" /><!-- 根据索引赋值 -->
<bean id="myStudent" class="com.wuuuula.Student">
<constructor-arg name="name" value="李四" />
<constructor-arg name="age" value="22" />
<!-- 引用类型 -->
<constructor-arg name="school" ref="mySchool" />
</bean>
<!-- 声明School对象 -->
<bean id="mySchool" class="com.wuuuula.School">
<property name="name" value="北京大学" />
<property name="address" value="北京市海淀区" />
</bean>
引用类型的自动注入
byName按名称自动注入
- java类中引用类型的属性名和spring容器(配置文件)中<bean>的id名称一样,且数据类型是一致的,这样的容器中的bean,spring能够赋值给引用类型。
- 语法:
<bean id="xxx" class="xxx" autowire="byName">
简单类型属性赋值
</bean>
byType按方式自动注入
- java类中引用类型的数据类型和spring容器(配置文件)中<bean>的class属性是同源关系,这样的bean能够赋值给引用类型
- 同源就是一类的意思:
- java类中引用类型的数据类型和bean的class的值是一样的。
- java类中引用类型的数据类型和bean的class值是父子类关系的。
- java类中引用类型的数据类型和bean的class的值是接口和实现类关系的。
- 语法:
<bean id="xxx" class="xxx" autowire="byType">
简单类型属性赋值
</bean>
基于注解的DI
<!-- 声明组件扫描器(component-scan),组件就是java对象
base-package:指定注解在你的项目中的包名。
component-scan工作方式:spring会扫描遍历base-package指定的包,
把包中和子包中的所有类,找到类中的注解,按照注解的功能创建对
象,或给属性赋值。
-->
<context:component-scan base-package="com.wuuuula" />
定义Bean的注解@Compoment
简单类型属性注入@Value
引用类型属性注入@Autowired
- @Autowired:spring框架提供的注解,实现引用类型的赋值
- spring中通过注解给引用类型赋值,使用的是自动注入原理,支持byName,byType
- @Autowired:默认使用的是byType自动注入。
- 属性:required,是一个boolean类型的,默认true
- required=true:表示引用类型赋值失败,程序报错,并终止执行。
- required=false:引用类型如果赋值失败,程序正常执行,引用类型是null
- 位置:
- 在属性定义的上面,无需set方法,推荐使用。
- 在set方法上面
- 例:
public class Student{
@Autowried
private School school;
/**
* @Autowried
* public void setSchool(School school){
* this.age = age;
* }
*/
}
- 如果要使用byName方式,需要做的是:
1. 在属性上面加入@Autowired
2. 在属性上面加入@Qualifier(value=“bean的id”):表示使用指定名称的bean完成赋值
public class Student{
@Autowried
@Qualifier("mySchool") // value可省略
private School school;
}
JDK注解@Resource自动注入
- @Resource:来自jdk中的注解,spring框架提供了对这个注解的功能支持,可以使用它给引用类型赋值。使用的也是自动注入原理,支持byName, byType . 默认是byName。
- 用法与@Autowired相似。默认使用byName;先使用byName自动注入,如果byName赋值失败,再使用byType
注解与XML的对比
注意
- spring默认创建对象的时间:在创建spring的容器时,会创建配置文件中的所有对象。
- spring创建对象:默认调用的是无参数构造方法