Spring ioc依赖倒置

所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B,反正A要用到B,则A依赖于B。
所谓倒置,你必须理解如果不倒置,会怎么着,因为A必须要有B,才可以调用B,如果不倒置,意思就是A主动获取B的实例:B new B(),这就是最简单的获取B实例的方法(当然还有各种设计模式可以帮助你去获得B的实例,比如工厂、Locator等等),然后你就可以调用b对象了。
所以,不倒置,意味着A要主动获取B,才能使用B;到了这里,你就应该明白了倒置的意思了。倒置就是A要调用B的话,A并不需要主动获取B,而是由其它人自动将B送上门来。


形象的举例就是:

通常情况下,假如你有一天在家里口渴了,要喝水,那么你可以到你小区的小卖部去,告诉他们,你需要一瓶水,然后小卖部给你一瓶水!

这本来没有太大问题,关键是如果小卖部很远,那么你必须知道:从你家如何到小卖部;小卖部里是否有你需要的水;你还要考虑是否开着车去;等等等等,也许有太多的问题要考虑了。也就是说,为了一瓶水,你还可能需要依赖于车等等这些交通工具或别的工具,问题是不是变得复杂了?那么如何解决这个问题呢?

解决这个问题的方法很简单:小卖部提供送货上门服务,凡是小卖部的会员,你只要告知小卖部你需要什么,小卖部将主动把货物给你送上门来!这样一来,你只需要做两件事情,你就可以活得更加轻松自在:
第一:向小卖部注册为会员
第二:告诉小卖部你需要什么

是不是和Spring的做法很类似呢?Spring就是小卖部,你就是A对象,水就是B对象
第一:在Spring中声明一个类:A
第二:告诉Spring,A需要B

假设A是UserAction类,而B是UserService类





     


在Spring这个商店(工厂)中,有很多对象/服务:userService,documentService,orgService,也有很多会员:userAction等等,声明userAction需要userService即可,Spring将通过你给它提供的通道主动把userService送上门来,因此UserAction的代码示例类似如下所示:

package org.leadfar.web;
public class UserAction{
     private UserService userService;
     public String login(){
          userService.valifyUser(xxx);
     }
     public void setUserService(UserService userService){ 
          this.userService userService;
     }
}

在这段代码里面,你无需自己创建UserService对象(Spring作为背后无形的手,把UserService对象通过你定义的setUserService()方法把它主动送给了你,这就叫依赖注入!)
<think>好的,用户想了解Spring框架中的依赖倒置依赖注入的概念及实现方式。首先,我需要确认这两个概念的定义以及它们在Spring中的具体应用。 依赖倒置原则(DIP)是SOLID原则中的一部分,强调高层模块不应依赖低层模块,两者都应依赖抽象。而依赖注入(DI)是实现控制反转(IoC)的一种方式,通过外部注入依赖对象,减少耦合。 接下来,要结合用户提供的引用内容。引用2和4提到依赖注入的三种方式:属性注入、构造方法注入和Setter注入,并且引用了@Component注解和Bean的配置。引用5提到了depends-on属性,这可能与依赖管理有关,但用户的问题主要集中在依赖倒置和注入上。 用户可能需要区分依赖倒置依赖注入的不同,以及它们如何在实际中应用。需要举例说明,比如使用接口和实现类,通过Spring的配置来注入依赖。同时,要确保使用正确的代码示例,比如用@Component和@Autowired,或者XML配置的方式。 还要注意用户提到的实现方式,可能需要对比不同的注入方法,并说明Spring容器如何管理这些依赖。例如,构造器注入推荐用于强制依赖,而Setter注入适合可选依赖。同时,自动配置和组件扫描也是关键点,如引用3中提到的@Component的作用。 需要检查是否有遗漏的信息,比如依赖倒置Spring中的具体体现,比如通过接口编程,而SpringIoC容器负责实例化和注入具体的实现类。这可能涉及到Bean的配置和自动装配机制。 最后,生成相关问题时要涵盖原理、实现方式、示例比较以及设计原则,确保用户能进一步探索相关内容。</think>### Spring框架中的依赖倒置依赖注入 #### 一、依赖倒置原理(DIP) 依赖倒置原则(Dependency Inversion Principle, DIP)是SOLID设计原则之一,核心思想是: 1. **高层模块不依赖低层模块**,两者都应依赖抽象(接口或抽象类); 2. **抽象不应依赖细节**,细节应依赖抽象。 在Spring中,这一原则通过**控制反转(IoC)容器**实现。Spring容器负责管理对象的生命周期和依赖关系,开发者只需定义接口,具体实现由容器动态注入[^1][^2]。 #### 二、依赖注入实现方式 依赖注入(Dependency Injection, DI)是Spring实现DIP的核心技术,具体方式包括: 1. **构造方法注入**(推荐方式) ```java public class UserService { private final UserRepository userRepository; @Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; } } ``` 特点:强制依赖、线程安全、适合不可变对象[^4]。 2. **Setter注入** ```java public class PaymentService { private PaymentGateway gateway; @Autowired public void setGateway(PaymentGateway gateway) { this.gateway = gateway; } } ``` 特点:适合可选依赖或需要重新配置的场景[^4]。 3. **属性注入** ```java @Component public class OrderService { @Autowired private InventoryService inventoryService; } ``` 特点:简洁但可能隐藏依赖关系,不推荐用于强制依赖[^3][^4]。 #### 三、Spring实现示例 以下通过接口与实现类的组合展示DIP+DI的典型应用: 1. **定义抽象层** ```java public interface DataRepository { String fetchData(); } ``` 2. **实现具体类** ```java @Component public class JdbcRepository implements DataRepository { public String fetchData() { return "Data from database"; } } ``` 3. **注入依赖** ```java @Service public class BusinessService { private final DataRepository repository; @Autowired public BusinessService(DataRepository repository) { this.repository = repository; // 实际注入JdbcRepository实例 } } ``` #### 四、依赖管理机制 Spring通过以下方式实现依赖解析: 1. **类型匹配**:根据接口类型查找实现类 2. **@Qualifier注解**:解决多个同类型Bean的冲突 3. **组件扫描**:通过@ComponentScan自动发现Bean[^3] 4. **显式配置**:XML或JavaConfig定义Bean依赖[^5] ### 对比总结 | 特性 | 依赖倒置原则 | 依赖注入 | |-------------------|----------------------------------|-----------------------------------| | **关注点** | 设计层面的抽象解耦 | 实现依赖关系的具体传递方式 | | **实现手段** | 接口/抽象类定义 | @Autowired、构造器、Setter等方法 | | **Spring支持** | 通过IoC容器天然支持 | 多种注入方式与自动装配机制 | 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值