Spring中的依赖注入(2)
一、背景
实现控制反转(Ioc)的方式有很多种,依赖注入(DI)是实现控制反转的一种方法.
1.有数据层dao包和服务层service包
1.1接口UserDao
在UserDao接口中定义了一个getUserName方法
它有两个实现类UserDaoImplByMysql与UserDaoImplByOracle
UserDaoImplByMysql代码如下
UserDaoImplByOracle代码如下
1.2接口UserService
在UserService接口中定义了一个outUserName()方法
它有一个实现类UserServiceImpl
UserServiceImpl代码如下
2.使用service完成操作
可以看到程序输出
二、分析
1.修改显示的值
在上面的内容中我们看到userService.outUserName()在执行后输出了
为什么会是这个结果?这还得回到UserServiceImpl的代码中
我们看到在代码的第6行调用了userDao.getUserName();
而这个userDao是谁呢?
在代码的第3行指定了
现在问题来了,我们想修改为UserDaoImplByOracle()来实现?
可以更改上面userDao的具体实现类
程序输出了我们想要的结果
通过上面的方式,虽然能达到结果,但是我们得修改掉原来的代码
在调用userDao时,我们就得明确的指明它的实现类.
2.改进
我们是否可以每次为userService动态的指定其中的userDao呢?
修改我们的代码,变成下面这样.
现在我们再修改测试类
注:
UserService userService = new UserServiceImpl();
左侧是UserService类型,是找不到setUserDao()方法的.
所以在setUserDao()方法之前进行了类型转换.
( (UserServiceImpl) userService).xx
现在我们通过set方法为其注入了UserDaoImplByMysql对象,再次运行.
为其set进不同的值,例如.
同样能成功输出想要的内容
3、对比
一开始是程序主动设置userDao对象,现在变成了程序被动的接收userDao对象.
我们可以看到,通过后者,无需更改UserServiceImpl中的任何内容.
只是在使用通过set注入,即可实现想要的效果.
当写了新的userDao时,例如.
输出值即可改变
通过上面的方式,写代码时不用再去管理对象的创建了.
例如UserServiceImpl中的userDao对象我们不用显示的指明,而是可以从外部动态的(被动的)接收.
我还没工作啊我设想一下,controller层调用service层吧.
我们是不是可以直接在controller中写判断之类的,然后根据情况动态的set进去业务对象,实现不同的业务逻辑.
这样控制权就交给了用户,用户来选择执行哪个业务方法?
控制反转,现在是不是反转了.
这就是Ioc的原型.
三、Spring中的Ioc
1.xml文件
创建一个pojo包,里面创建一个User类,包含一个成员变量username.
为其设置上set方法和toString方法.
在xml文件中声明一个对应的bean.
编写测试类.
运行后,可以看到username成功注入"yang".
tUser对象是谁创建的?
Spring创建的
tUser对象的属性怎么设置的?
Spring容器设置的
总结
控制反转,把控制权转交给了Spring容器(<beans></beans>
包裹).
我们使用的时候从Spring容器中拿就可以了,不用我们new对象.
即使用了Spring框架后,对象是由Spring创建的.
Spring通过依赖注入的方式完成了控制反转.
set方式注入
在User中注释掉set方法
扩展
在xml中注释掉property.
点击可以跳转到相应的位置
同理,类前方也会有Spring的标志
看到这些标志就说明已经被Spring托管了.
下面前面提到的UserServiceImpl进行配置
测试类
输出结果
还记得前面是在Java代码中set进去值吗?
现在都不用在Java代码写这个东西了,交给Spring后,直接修改xml文件,指明ref后,即可达到目的.
我们只管写代码,完了在xml做好配置就好了.
Spring的Ioc:对象由Spring来创建、管理、装配.
2.Ioc如何创建对象
在上文中,我们构建bean后,通过property为其set进去了值.
即我们了解到<bean></bean>
标签可以完成对象的创建.
现在是先构造,再进行property为其set进去值.
那么是否和类一样,存在构造函数的方式呢?
注释掉<property></property>
标签,现在我们研究一下SpringBean如何实现构造函数.
现在情况如下.
- 类User
注意此时我们关注的是构造函数,所以没有写出username属性的set方法.
- xml文件
- 测试类
显示写出无参构造函数
运行测试类,输出.
得知,默认执行无参构造函数.
查阅Spring文档,在1.4.1节可以找到有参构造的三种书写方式.
增加有参构造函数.
(1)构造函数参数类型匹配
xml文件
指明了构造函数,无参函数"我是无参构造函数"不再输出,结果如下.
(2)构造函数参数索引(0开始)
xml文件
结果
尝试把第二个形参值,即下标1处的int赋值为字符串"abc",很智能,直接报错.
(3)构造函数参数名称
xml文件
个人觉得用参数名字比较方便吧(参数类型可能重复,参数下标也不好数.)
在注册bean的时候就会给我们创建对象
测试类用的bean是user,这个otherUser没有用.
结果第一行显示otherUser对象也会被创建.
无论是否使用,Spring容器在启动时就会创建完成注册的bean对象,等需要用了自己取就好.
例如:不管你家有没有打野位置,野怪都会生成,想打了去打就好了.
修改测试类,获取同一个bean.
结果显示true
,说明这个bean的实例只有一份.
总结
<beans></beans>
标签包裹着我们的<bean></bean>
标签.
beans就相当于Spring容器,bean就是容器里的东西.
无论用不用,Spring容器在启动时就会将注册的bean创建,需要了获取即可.
Sring实现控制反转有无参构造后set方式注入与直接通过构造函数注入这两种常见方式(依赖注入).
3.依赖注入
- 依赖:bean对象的创建依赖于bean容器
- 注入:bean对象的属性通过bean容器注入
__EOF__

本文链接:https://www.cnblogs.com/yang37/p/12811265.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具