0

0

轻松了解Spring中的控制反转和依赖注入

高洛峰

高洛峰

发布时间:2016-10-17 09:27:04

|

2005人浏览过

|

来源于php中文网

原创

  我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达170平方米,重达30吨,到现如今的个人笔记本,事物更加轻量功能却更加丰富,这是事物发展过程中的一个趋势,在技术领域中同样也是如此,企业级javabean(enterprise javabean ,ejb)在创建之初是非常成功,但是时间一久人们便开始追逐更加方便更加简易和轻量级的技术框架实现,于是spring就应运而生,并且spring一直开始不断地涉及到其他领域(这里就不再多详谈了),而spring的精髓当中就包括控制反转和依赖注入。

 浅谈控制反转(Inversion of Control,IOC)

  我们首先先来了解一下控制二字,也就是在控制“正”转的情况下,在任何一个有请求作用的系统当中,至少需要有两个类互相配合工作,在一个入口类下使用new关键字创建另一个类的对象实例,这就好比在面向对象编程的思想下,“我“充当一个入口类,在这个入口类中,我每次吃饭的时候都要买一双一次性筷子(每一次使用都要new一次),在这样的关系下,是”我“(即调用者)每次都要”主动“去买一次性筷子(另一个类),我对筷子说你老老实实的过来我的手上,是我控制了筷子,那好,在这种控制正转的关系下,放在现实生活当中,肯定是不现实的,而且人是懒惰的,他总会去创造出更加方便自己生活的想法,更确切的做法是,买一双普通的筷子(非一次性),把他放在一个容器当中(在Spring中叫做IOC容器),你需要使用的时候就对容器说:IOC我想要用筷子(向容器发出请求),接着筷子就会”注入“到的手上,而在这个过程当中,你不再是控制方,反而演变成一名请求者(虽然本身还是调用者),依赖于容器给予你资源,控制权坐落到了容器身上,于是这就是人们俗称的控制反转。

 初涉依赖注入(Dependency Injection)  

  同样接着上面的例子,在控制反转的统一下,筷子是怎么来到我的手上(即我们是如何获得请求的类),这就是一个依赖注入的过程。

1.png

 再谈IOC与DI

  设计原则中好莱坞原则描述到,“别找我们,我们找你”,百度百科上对这点描述是“不要给我们打电话,我们会给你打电话(don‘t call us, we‘ll call you)”这是著名的好莱坞原则。在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项的完全控制,演员只能被动式的接受公司的差使,在需要的环节中,完成自己的演出。这一点完美的提现了在IOC身上,IOC所注重的是设计思想上,从一个常规的创建对象的做法,即new一个对象,转变成向IOC容器递交”简历“,被动的等待IOC容器返回资源给你。控制反转即指的是”演艺公司控制演员“,而说到依赖,则是“演员需要公司混饭”,我们所需求的对象,需要依赖容器来获得,这个过程即是依赖注入。本质上IOC和DI是同一思想下不同维度的表现。

 代码实现

  既然说在控制反转中获取资源的过程叫做依赖注入,那么这里代码实现也是专注于依赖注入。依赖注入有3种方式,分别为构造注入,设置注入,接口注入。

  1.接口注入:在接口中定义要注入的信息,并通过接口来完成注入。(Spring不支持这种注入方式--不支持的原因是--Spring声称其是非入侵式的《离开这个框架也能活》,如果使用接口注入的话,就违背了这一原则),这里不做代码实现讲解。

  2.setter注入

‎ Gemini Storybook
‎ Gemini Storybook

Google Gemini推出的AI绘本生成工具

下载

  我们先脱离Spring来实现setter注入

public interface UserDao{
  addUser(String username);      
}
public class UserDaoImpl implements UserDao{
    @Override    
    public void addUser(String username)
{
    System.out.println("添加用户:"+username);  
}  
}
public class UserMessage{    
    
    private UserDao userDao;    
    
    //使用设值方式赋值    
    public void setUserDao(UserDaoImpl userDao) {    
        this.userDao = userDao;    
    }    
        
    @Override    
    public void addUser(String userName, String password) {    
      
        userDao.addUser(userName, password);    
    }    
}

  我们仔细观察,其实这里的做法跟 UserDao userDao=new UserDaoImpl()做法本质是一样的,这里就不得不提到了多态,即父类可以引用子类的方法,在这里形成的一个效果就是降低了User Message和UserDao的耦合度。再想想,读者可能会说不对啊,你说的控制反转和依赖注入需要向容器请求资源,这个容器并没有在上面提现出来啊,下面我们就讲解一下Spring 中是如何做到注入的。

<!-- 使用spring管理对象的创建,还有对象的依赖关系 -->    
<bean id="userManager" class="scau.zzf.service.UserMessage">    
        <!-- (1)UserMessageImpl使用了userDao,Ioc是自动创建相应的UserDao实现,都是由容器管理-->    
        <!-- (2)在UserMessageImpl中提供构造函数,让spring将UserDao实现注入(DI)过来 -->    
        <!-- (3)让spring管理我们对象的创建和依赖关系,必须将依赖关系配置到spring的核心配置文件中 -->    
        <property name="userDao" ref="UserDao"></property>   
    <!-- 构造注入 -->
    <!-- <constructor-arg ref="userDao"/>  --> 
    </bean>   
<bean id="UserDao" class="scau.zzf.Dao.UserDao">
    
</bean>

  首先我们需要装配Bean,即在Spring容器中将Bean进行配置后,然后返回Bean对象实例。我们可以通过XmlBeanFactory读取我们xml文件,从而获取相关的Bean信息。

public class test {
    public static void main(String[] args) throws Exception {
    BeanFactory factory=new XmlBeanFactory(new FileSystemResource("src/appllication.xml"));
        UserMessage userMessage=(UserMessage)factory.getBean("UserMessage");
        userMessage.add("德玛西亚");

    }
}

  在实际应用当中,我们并不会手动去读取Xml中的信息或者加载配置文件,Spring底层已经帮我做好了这些,也就是在实际应用当中,我们就只是需要发送一个请求而已,当然了解这么一个过程还是很有必要的。

  下面再简单讲解一下如何通过注解来实现注入。

@Configuration
public class UserConfig {
    @Bean
    public UserDao getUserDao(){
        return new UserDao();
    }
    @Bean
    public UserMessage getUserMessage(){
        return new UserMesssgae(getUserDao);
    }
}

@Configuration的作用是使整个类成为一个配置类,@Bean注解会告诉Spring这个注解下的方法将会返回一个对象,这个对象要注册维Spring应用上下文的Bean。在默认情况下,Spring的Bean都是单例的,也就是再上面的例子当中,无论我们使用多少次getUserDao(),结果返回的对象至始至终都是相同的。关于JavaConfig的配置进一步相关说明,读者可以前往笔者的另一篇文章《更加优雅的配置SSH》中进行参考。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
chatgpt使用指南
chatgpt使用指南

本专题整合了chatgpt使用教程、新手使用说明等等相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

chatgpt官网入口地址合集
chatgpt官网入口地址合集

本专题整合了chatgpt官网入口地址、使用教程等内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

minimax入口地址汇总
minimax入口地址汇总

本专题整合了minimax相关入口合集,阅读专题下面的文章了解更多详细地址。

4

2026.03.16

C++多线程并发控制与线程安全设计实践
C++多线程并发控制与线程安全设计实践

本专题围绕 C++ 在高性能系统开发中的并发控制技术展开,系统讲解多线程编程模型与线程安全设计方法。内容包括互斥锁、读写锁、条件变量、原子操作以及线程池实现机制,同时结合实际案例分析并发竞争、死锁避免与性能优化策略。通过实践讲解,帮助开发者掌握构建稳定高效并发系统的关键技术。

7

2026.03.16

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

114

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

141

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

396

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

65

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

111

2026.03.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号