当前位置: 首页 > news >正文

DI依赖注入

依赖注入(Dependency Injection)

依赖注入(DI)是控制反转(IoC)的一种实现方式,核心思想是:将类所依赖的对象通过外部注入,而非类内部自行创建,从而降低类之间的耦合度。简单来说,就是“给某个类中的属性赋值”,但赋值过程由外部容器(如Spring)管理。

依赖注入的常见方式

1. 构造器注入

通过类的构造方法传递依赖对象,容器在创建对象时调用构造器并传入所需的依赖。

适用场景:依赖必须存在(不可缺省),且创建后不允许修改的场景。

代码示例

// 被依赖的类
public class UserDao {public void addUser() {System.out.println("添加用户到数据库");}
}// 依赖注入的类(通过构造器注入UserDao)
public class UserService {private UserDao userDao;// 构造器注入:通过构造方法接收依赖public UserService(UserDao userDao) {this.userDao = userDao;}public void register() {userDao.addUser(); // 使用注入的依赖}
}// Spring配置文件(applicationContext.xml)
<bean id="userDao" class="com.example.UserDao"/>
<bean id="userService" class="com.example.UserService"><!-- 构造器注入:通过name指定构造方法参数名,ref引用其他bean --><constructor-arg name="userDao" ref="userDao"/>
</bean>

2. Set方法注入

通过类的setter方法为属性赋值,容器在创建对象后调用set方法注入依赖。

适用场景:依赖可选(可缺省),或需要在对象创建后动态修改依赖的场景。

支持的注入类型:
  • 基本数据类型(int、String等)
  • 引用数据类型(其他Bean)
  • 集合类型(List、Map、Set等)

代码示例

public class OrderService {// 基本类型属性private String serviceName;private int maxOrderCount;// 引用类型属性private UserDao userDao;// 集合类型属性private List<String> orderTypes;private Map<String, Integer> orderLimits;// Setter方法(用于注入)public void setServiceName(String serviceName) {this.serviceName = serviceName;}public void setMaxOrderCount(int maxOrderCount) {this.maxOrderCount = maxOrderCount;}public void setUserDao(UserDao userDao) {this.userDao = userDao;}public void setOrderTypes(List<String> orderTypes) {this.orderTypes = orderTypes;}public void setOrderLimits(Map<String, Integer> orderLimits) {this.orderLimits = orderLimits;}// 测试方法public void showInfo() {System.out.println("服务名称:" + serviceName);System.out.println("最大订单数:" + maxOrderCount);System.out.println("关联的UserDao:" + userDao);System.out.println("订单类型:" + orderTypes);System.out.println("订单限额:" + orderLimits);}
}// Spring配置文件(applicationContext.xml)
<bean id="userDao" class="com.example.UserDao"/><bean id="orderService" class="com.example.OrderService"><!-- 基本类型注入 --><property name="serviceName" value="订单服务"/><property name="maxOrderCount" value="100"/><!-- 引用类型注入(ref指向其他bean) --><property name="userDao" ref="userDao"/><!-- 集合类型注入 --><property name="orderTypes"><list><value>普通订单</value><value>秒杀订单</value></list></property><property name="orderLimits"><map><entry key="普通订单" value="50"/><entry key="秒杀订单" value="10"/></map></property>
</bean>

3. 命名空间注入(c命名和p命名)

通过XML命名空间简化注入配置,本质是构造器注入和set方法注入的语法糖。

(1)p命名空间注入(对应set方法注入)
  • 需在XML中声明命名空间:xmlns:p="http://www.springframework.org/schema/p"
  • 语法:p:属性名="值"(基本类型)或 p:属性名-ref="beanId"(引用类型)

代码示例

<!-- 声明p命名空间 -->
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userDao" class="com.example.UserDao"/><!-- p命名空间注入(等价于set方法注入) --><bean id="orderService" class="com.example.OrderService"p:serviceName="订单服务"p:maxOrderCount="100"p:userDao-ref="userDao"/> <!-- 引用类型用-ref -->
</beans>
(2)c命名空间注入(对应构造器注入)
  • 需在XML中声明命名空间:xmlns:c="http://www.springframework.org/schema/c"
  • 语法:c:参数名="值"(基本类型)或 c:参数名-ref="beanId"(引用类型)

代码示例

<!-- 声明c命名空间 -->
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userDao" class="com.example.UserDao"/><!-- c命名空间注入(等价于构造器注入) --><bean id="userService" class="com.example.UserService"c:userDao-ref="userDao"/> <!-- 构造方法参数名为userDao -->
</beans>

总结

  • 构造器注入:通过构造方法传递依赖,适合必填依赖。
  • Set方法注入:通过setter方法赋值,支持多种数据类型,适合可选依赖。
  • 命名空间注入:c命名(构造器)和p命名(set方法)的简化语法,减少XML配置冗余。

依赖注入的核心是“解耦”,让类更专注于自身业务逻辑,而非依赖对象的创建。

http://www.jsqmd.com/news/37761/

相关文章:

  • 解码LVGL定时器
  • ORACLE解析游标生成JSON
  • 习题解析之:鸡兔同笼
  • 如何选择锡林郭勒西林瓶灌装旋盖机?环境温湿度要求详解
  • DeepSeek权威测评榜单2025年11月最新geo优化公司推荐
  • ECB33-PGB2N4E32-I单板机智能交通监控应用方案解析
  • 北京GEO优化服务商2025权威推荐:抢占AI搜索流量新入口
  • 雅思报班哪个机构比较好?过来人分享选择经验与价格课程对比
  • 深入解析:第三方课题验收测试机构:【API测试工具Apifox使用指南】
  • 云原生周刊丨runc 三大高危漏洞曝光
  • Web Worker 入门指南
  • 鸿蒙NEXT系列之精析NDK UI API(节点增删和属性设置) - 实践
  • 通用cursor rules总结
  • 【JVS更新日志】开源框架升级vue 3、低代码、企业计划、智能BI及其他产品迎来新版本! - 实践
  • 银川西林瓶灌装旋盖机推荐2025,运行稳定连续8小时无故障
  • 【ACM出版 | EI检索稳定】2025年人工智能、业务转型和数据科学创新国际学术会议(ICBTDS 2025)
  • echarts 树形结构图实例
  • pg_hba.conf配置里peer,indent和md5的区别
  • 基于Simulink的双电机PID控制仿真实现方案
  • 锡林郭勒西林瓶灌装清洗耗材月成本分析?查行情享优惠
  • AI Agent OS 探索有价值的论文分析(1):Sleep-time Compute
  • Linux内核架构浅谈26-Linux实时进程调度:优先级反转与解决实用的方案
  • 宏定义的高级应用
  • 被问性能后,我封装了这个 PHP 错误上报工具
  • 公众号中的贴纸素材有什么作用?在哪里找?
  • 国标GB28181算法算力平台EasyGBS:深度解析全场景视频调阅功能与行业实战应用
  • 2025出国留学机构综合实力榜:排名前十的留学中介特色分析
  • 公众号怎么起爆款标题?有什么好用的工具?
  • 邢台西林瓶灌装机优选指南:聚焦资质、案例与售后
  • 基于SpringBoot+Vue的个人理财系统管理系统设计与建立【Java+MySQL+MyBatis完整源码】