Spring依赖注入(DI)的三种方式详解(附完整代码示例)

Spring依赖注入(DI)的三种方式详解(附完整代码示例)

依赖注入(Dependency Injection)是Spring框架的核心特性,它实现了对象之间的解耦。本文将详细介绍三种常用的依赖注入方式,并结合实际代码演示其应用。

1. Setter方法注入(设置值注入)

原理:通过调用Bean的setter方法注入属性值

特点:灵活,可选择性注入部分属性

XML配置:

Java代码:

@Test

public void run1(){

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

User user1 = (User) context.getBean("user");

System.out.println(user1.toString());

// 输出: User{username='张三', age=18, gender='男'}

}

测试代码:

@Test

public void run1(){

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

User user1 = (User) context.getBean("user");

System.out.println(user1.toString());

// 输出: User{username='张三', age=18, gender='男'}

}

优势:

可单独注入特定属性

支持重新注入(属性可变)

与构造器注入互补

2. 构造器注入

原理:通过构造函数参数注入属性值

特点:创建对象时即完成初始化,属性不可变

XML配置:

Java代码:

设置完有参的构造器一定要将无参的构造器一并写出:因为默认使用的是无参构造器的方法,一旦设置有参不设置无参找不到就会报错

public class User {

// 带参构造器

public User(String username, Integer age, String gender) {

this.username = username;

this.age = age;

this.gender = gender;

}

}

测试代码:

@Test

public void run2(){

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

User user2 = (User) context.getBean("user2");

System.out.println(user2.toString());

// 输出: User{username='李四', age=19, gender='男'}

}

优势:

确保完全初始化的对象

适合必需依赖项

线程安全(属性不可变)

3. P命名空间注入

原理:XML简写语法,本质是setter注入的快捷方式

特点:配置简洁,支持对象引用注入

XML配置:

xmlns:p="http://www.springframework.org/schema/p"

p:username="花花"

p:age="20"

p:gender="女"

p:hajimi-ref="user2"/>

Java代码:

public class User {

// 对象引用属性

private User hajimi;

public void setHajimi(User hajimi) {

this.hajimi = hajimi;

}

}

测试代码:

@Test

public void run3(){

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

User user3 = (User) context.getBean("user3");

System.out.println(user3.toString());

// 获取注入的对象引用

User hajimiUser = user3.getHajimi();

System.out.println(hajimiUser.toString());

/* 输出:

User{username='花花', age=20, gender='女'}

User{username='李四', age=19, gender='男'}

*/

}

优势:

配置简洁明了

支持基本类型和对象引用(-ref)注入

减少XML配置量

三种注入方式对比

特性Setter注入构造器注入P命名空间注入配置语法p:属性名="值"对象引用p:属性名-ref=""灵活性⭐⭐⭐ (可部分注入)⭐ (需全参数)⭐⭐ (类似setter)不变性❌ (属性可变)✅ (属性不可变)❌ (属性可变)适用场景可选依赖项必需依赖项简洁配置循环依赖支持不支持支持

对象引用注入详解

在Spring中,可以注入其他Bean作为属性,形成对象关联:

Java:

public class User {

private User hajimi; // 引用其他User对象

}

XML配置:

p:hajimi-ref="user2"/>

对象关系图:

user3 ────┬──▶ username: "花花"

├──▶ age: 20

└──▶ hajimi ────┬──▶ username: "李四" (user2)

├──▶ age: 19

└──▶ gender: "男"

最佳实践建议

首选构造器注入(强制依赖)

// 确保必需依赖项在构造时提供

public class OrderService {

private final PaymentService paymentService;

public OrderService(PaymentService paymentService) {

this.paymentService = paymentService;

}

}

Setter注入用于可选依赖

// 可选日志依赖

public class ProductService {

private Logger logger;

public void setLogger(Logger logger) {

this.logger = logger;

}

}

P命名空间简化配置

p:jdbcUrl="jdbc:mysql://localhost/db"

p:username="root"

p:password="secret"/>

避免的常见错误

缺少setter方法(setter注入)

构造器参数不匹配(构造器注入)

对象引用未定义(p:属性名-ref)

循环依赖(A依赖B,B又依赖A)

完整项目结构

src

├── main

│ ├── java

│ │ ├── com.qcby

│ │ │ └── DI.java # 测试类

│ │ └── com.qcby.entity

│ │ └── User.java # 实体类

│ └── resources

│ └── spring.xml # Spring配置

通过合理运用这三种依赖注入方式,可以构建松耦合、易测试的应用程序。Spring的DI机制让对象协作变得简单而优雅。

相关推荐

天天快递
365bet客户端下载

天天快递

📅 08-07 👁️ 8732
【涨姿势】能放6天假的APEC为什么这么牛?
365bet娱乐场平台

【涨姿势】能放6天假的APEC为什么这么牛?

📅 08-29 👁️ 8102
庄子《逍遥游》:北冥在哪里,它又象征什么?
365bet客户端下载

庄子《逍遥游》:北冥在哪里,它又象征什么?

📅 09-06 👁️ 429