目录
构造函数注入
setter注入
Spring 依赖注入(Dependency Injection,DI)和控制反转含义相同,它们是从两个角度描述的同一个概念。使用依赖注入可以更轻松的管理和测试应用程序。
当某个 Java 实例需要另一个 Java 实例时,传统的方法是由调用者创建被调用者的实例(例如,使用 new 关键字获得被调用者实例),而使用 Spring 框架后,被调用者的实例不再由调用者创建,而是由 Spring 容器创建,这称为控制反转。
Spring 容器在创建被调用者的实例时,会自动将调用者需要的对象实例注入给调用者,调用者通过 Spring 容器获得被调用者实例,这称为依赖注入。
依赖注入主要有两种实现方式,分别是 setter 注入(又称设值注入)和构造函数注入。具体介绍如下。
1)构造函数注入
指 IoC 容器使用构造函数注入被依赖的实例。可以通过调用带参数的构造函数实现依赖注入,每个参数代表一个依赖。(就是在创建的时候带上参数值)
2)setter 注入
指 IoC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参 static 工厂方法实例化 Bean 后,调用该 Bean 的 setter 方法,即可实现基于 setter 的 DI。(使用setter方法变更属性)
在 Spring 实例化 Bean 的过程中,首先会调用默认的构造方法实例化 Bean 对象,然后通过 Java 的反射机制调用 setXxx() 方法进行属性的注入。因此,setter 注入要求 Bean 的对应类必须满足以下两点要求。// 必须先实例化(构造函数),然后才能初始化(init等)
必须提供一个默认的无参构造方法。必须为需要注入的属性提供对应的 setter 方法。
使用 setter 注入时,在 Spring 配置文件中,需要使用
而使用构造注入时,在配置文件中,主要使用
构造函数注入
下面使用
在
下面使用 IntelliJ IDEA 演示通过构造函数注入依赖项,步骤如下:
- 创建 Spring 项目,并在 src 目录下创建 com.spring_learn 包。在 com.spring_learn 包下创建 Person、Man 和 MainApp 类。在 src 目录下创建 Spring 配置文件 Beans.xml(附:java配置方式PersonConfiguration)。运行 Spring 项目。
Man 类代码如下。
public class Man {
private String name;
private int age;
public Man() {
System.out.println("man的无参构造函数");
}
public Man(String name, int age) {
System.out.println("man的有参构造函数");
this.name = name;
this.age = age;
}
public void show() {
System.out.println("名称:" + name + "n年龄:" + age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Person 类代码如下。
public class Person {
private Man man;
public Person(Man man) {
System.out.println("Person的有参构造函数");
this.man = man;
}
public void man() {
man.show();
}
}
Beans.xml 配置文件如下
MainApp 类代码如下。
public class MainApp {
public static void main(String[] args) {
//注解方式
//AbstractApplicationContext context = new AnnotationConfigApplicationContext(PersonConfiguration.class);
//xml方式
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
Person obj = (Person) context.getBean("person");
obj.man();
}
}
运行结果如下。
附:java配置方式PersonConfiguration
@Configuration
public class PersonConfiguration {
@Bean("man") //@Bean的原理
public Man getMan(){
Man man = new Man("Swadian2008",18);
//System.out.println("getMan:"+man.hashCode()); 同一个对象
return man;
}
@Bean("person")
public Person getPerson(){
Person person = new Person(getMan());//构造函数注入
return person;
}
}
setter注入
下面使用
在
在上例的基础上修改 Person 类的内容,代码如下。
public class Person {
private Man man;
//添加无参构造
public Person() {
System.out.println("Person的无参构造函数");
}
public Person(Man man) {
System.out.println("Person的有参构造函数");
this.man = man;
}
//添加setter方法
public void setMan(Man man) {
System.out.println("使用setMan方法");
this.man = man;
}
public void man() {
man.show();
}
}
Beans.xml 配置文件如下。
运行结果如下。
附:java配置方式PersonConfiguration
@Configuration
public class PersonConfiguration {
@Bean("man") //@Bean的原理
public Man getMan(){
Man man = new Man("Swadian2008",18);
//System.out.println("getMan:"+man.hashCode()); 同一个对象
return man;
}
@Bean("person")
public Person getPerson(){
Person person = new Person();
person.setMan(getMan());//setter注入
return person;
}
}


