Spring中的depends-on
depend-on用来表示一个Bean的实例化依靠另一个Bean先实例化。如果在一个bean A上定义了depend-on B那么就表示:A 实例化前先实例化 B。
这种情况下,A可能根本不需要持有一个B对象。
比如说,你的DAO Bean实例化之前你必须要先实例化Database Bean,DAO Bean并不需要持有一个Database Bean的实例。因为DAO的使用是依赖Database启动的,如果Database Bean不启动,那么DAO即使实例化也是不可用的。这种情况DAO对Database的依赖是不直接的。
除了在DAO上使用构造函数注入Database Bean以外,Spring没有任何依赖注入的关系能够满足上面的情况。但是DAO也许根本不需要Database的实例被注入,因为DAO是通过JDBC访问数据库的,它不需要调用Database 上的任何方法和属性。
在这种情况下你可以使用depends-on来定义在DAO被实例化之前先去实例化Database。你可这样定义:
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
4 "http://www.springframework.org/dtd/spring-beans.dtd">
5 <beans>
6 <bean name="dao" class="research.spring.beanfactory.ch3.Dao" depends-on="database">
7 </bean>
8 <bean id="database" class="research.spring.beanfactory.ch3.Database">
9 </bean>
10 </beans>
通过定义depends-on=”database”可以控制Sping实例化dao的顺序。在任何时候Spring总会保证实例化DAO之前先实例Database。
通常depends-on常常应用在上面的场景中。如果DAO depend-on Database的同时需要得到Database的实例,那么使用构造函数注入是一个比较好的解决办法。因为构造函数注入的方式是要先实例化目标对象依赖的对象然后在实例化目标对象。关于构造函数的输入请参考另一篇文章《Spring内核研究-set方法注入和构造函数注入》
DAO depend-on Database时,也可以在DAO上定义setDatabase方法来接收一个Database的实例。这样Sping会保证DAO创建前先创建Database实例,然后在把实例化DAO后调用DAO的setDatabase方法把刚才创建的Database的实例注入给DAO。前提条件时Database必须定义成单例的。否则Spring在DAO depend-on Database时会创建一个Database的实例,在DAO.setDatabase时又会创建Database另外的一个实例。这种情况可能不是你想要的,而且很可能会造成比较隐蔽的错误。
使用set方法注入depend-on的对象:
1 ?xml version="1.0" encoding="UTF-8"?>
2
3 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
4 "http://www.springframework.org/dtd/spring-beans.dtd">
5 <beans>
6
7 <bean name="dao" class="research.spring.beanfactory.ch3.Dao" depends-on="database ">
8 <property name="database">
9 <ref bean="database"></ref>
10 </property>
11 </bean>
12 <bean id="database" class="research.spring.beanfactory.ch3.Database">
13 </bean>
14 </beans>
一般在depends-on一个对象并且又需要这个对象实例的情况下,我都建议你使用构造函数的注入方式替换depend-on。只有不能构造函数中添加依赖对象参数的情况下才使用上面例子里的方式。
可以同时使用depends-on和构造函数注入,如A depends-on B 并且 new A(B b)。
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
4 "http://www.springframework.org/dtd/spring-beans.dtd">
5 <beans>
6 <bean name="dao" class="research.spring.beanfactory.ch3.Dao" depends-on="database">
7 <constructor-arg>
8 <ref bean="database"></ref>
9 </constructor-arg>
10 </bean>
11 <bean id="database" class="research.spring.beanfactory.ch3.Database">
12
13 </bean>
14 </beans>
然而这种做法是不合适的,因为在构在函数中注入依赖对象的方式可以包含depends-on的情况。也就时说new A(B b)包含了A depends-on B的所有情况。既然已经定义了new A(B b)就没有必要在定义A depends-on B。所以,new A(B b)可以替代A depends-on B。在A创建前必须创建B,而且A不需要使用B实例的情况下只能使用A depends-on B。
Spring允许Bean和Bean依赖的Bean(合作者)上同时定义depends-on。比如A depends-on B && B depends-on C && C depends-on D。下面这样定义是合法的。Sping实例化他们的顺序是D->C->B->A。
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
4 "http://www.springframework.org/dtd/spring-beans.dtd">
5 <beans>
6 <bean name="a" class="research.spring.beanfactory.ch3.A" depends-on="b" />
7 <bean name="b" class="research.spring.beanfactory.ch3.B" depends-on="c" />
8 <bean name="c" class="research.spring.beanfactory.ch3.C" depends-on="D" />
9 <bean name="d" class="research.spring.beanfactory.ch3.D" />
10
11 </beans>
但是Spring不允许A depends-on B && B depends-on A的情况。看下面的例子,由于D又依赖回A,这种在依赖关系中形成了一个闭环,Spring将无法处理这种依赖关系。所以下面的这种定义是不合法的。
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
4 "http://www.springframework.org/dtd/spring-beans.dtd">
5 <beans>
6 <bean name="a" class="research.spring.beanfactory.ch3.A" depends-on="b" />
7 <bean name="b" class="research.spring.beanfactory.ch3.B" depends-on="c" />
8 <bean name="c" class="research.spring.beanfactory.ch3.C" depends-on="D" />
9 <bean name="d" class="research.spring.beanfactory.ch3.D" depends-on="A"/>
10
11 </beans>
一个Bean可以同时depends-on多个对象如,A depends-on D,C,B。可以使用“,”或“;”定义多个depends-on的对象。
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
4 "http://www.springframework.org/dtd/spring-beans.dtd">
5 <beans>
6 <bean name="a" class="research.spring.beanfactory.ch3.A" depends-on="d,c,b" />
7 <bean name="b" class="research.spring.beanfactory.ch3.B" />
8 <bean name="c" class="research.spring.beanfactory.ch3.C" />
9 <bean name="d" class="research.spring.beanfactory.ch3.D" />
10
11 </beans>
上面的例子中A的实例化需要先实例化D,C,B。Spring会按照depend-on中定义的顺序来处理Bean。在这个例子里Spring实例化对象的顺利是D->C->B->A。虽然实例化对象的顺序和前面“A depends-on B && B depends-on C && C depends-on D”的情况一下,但是这里的意义是完全不同的。不能用“A depends-on D,C,B”代替“A depends-on B && B depends-on C && C depends-on D”。
depends-on是一个非常又用的功能,借助depends-on我们可以管理那些依赖关系不明显或者没有直接依赖关系的对象。
————————————————
版权声明:本文为CSDN博主「Terry_dong」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sjyttkl/article/details/72774015
Spring中的depends-on相关推荐
- Spring中Bean的生命周期以及三级缓存介绍
Bean的生命周期以及三级缓存介绍 简述 测试代码编写 创建IOC容器(Bean创建) 1.refresh()方法 2.finishBeanFactoryInitialization(beanFact ...
- Spring中解决循环引用
目录 一.前言 二.源码分析 1.getBean(String name)方法 2.getSingleton(beanName)方法 3.getSingleton(String beanName, O ...
- 谈谈Spring中的对象跟Bean,你知道Spring怎么创建对象的吗?
本系列文章: 读源码,我们可以从第一行读起 你知道Spring是怎么解析配置类的吗? 配置类为什么要添加@Configuration注解? 推荐阅读: Spring官网阅读 | 总结篇 Spring杂 ...
- spring中IOC是什么意思 个人觉得解释的非常有意思
用一个直观的列子来告诉大家:在spring中什么是ioc IoC就是Inversion of Control,控制反转.在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控 ...
- Spring中配置DataSource数据源的几种选择
Spring中配置DataSource数据源的几种选择 在Spring框架中有如下3种获得DataSource对象的方法: 从JNDI获得DataSource. 从第三方的连接池获得DataSourc ...
- 详解设计模式在Spring中的应用
设计模式作为工作学习中的枕边书,却时常处于勤说不用的尴尬境地,也不是我们时常忘记,只是一直没有记忆. 今天,螃蟹在IT学习者网站就设计模式的内在价值做一番探讨,并以spring为例进行讲解,只有领略了 ...
- Spring中利用applicationContext.xml文件实例化对象和调用方法
Spring中实例化对象和调用方法入门 1.jar包和xml的准备 已上传至百度云盘,链接: https://pan.baidu.com/s/1CY0xQq3GLK06iX7tVLnp3Q 提取码: ...
- 【spring 5】AOP:spring中对于AOP的的实现
在前两篇博客中,介绍了AOP实现的基础:静态代理和动态代理,这篇博客介绍spring中AOP的实现. 一.采用Annotation方式 首先引入jar包:aspectjrt.jar && ...
- Spring中WebApplicationContext
ApplicationContext是Spring的核心,Context我们通常解释为上下文环境,我想用"容器"来表述它更容易理解一 些,ApplicationContext则是& ...
- Spring中使用Schedule调度
在spring中两种办法使用调度,以下使用是在spring4.0中. 一.基于application配置文件,配置入下: 1 <bean id="jobDetail" cla ...
最新文章
- c语言删除偶数号节点,第十二周作业
- postgresql 可调试
- 对 jiffies 溢出、回绕及 time_after 宏的理解
- python面试-10个Python面试常问的问题(小结)
- 基于VB和EXCEL的报表设计及打印
- HH SaaS电商系统的商品物流模板的功能设计
- 数据3分钟丨Databricks与Snowflake开撕;阿里云多款自研数据库支撑首个“100%云上双11”...
- 关于gcc -o 的使用问题
- Android 打包keysotre文件
- 每日算法系列【LeetCode 495】提莫攻击
- 工程师如何优雅的拒绝不合理需求
- 小明左右手分别拿两张纸牌:黑桃10和红心8,现在交换手中的牌。编写并输出互换后的结果,输出结果如图所示。
- android tf卡 修复工具,如何修复/格式化损坏的安卓手机SD卡-万兴恢复专家
- 【Matlab车牌识别】BP神经网络车牌识别【含GUI源码 669期】
- VIM-Plug安装插件失败,更换源
- 《数论概论》读书笔记 第三章勾股数组与单位圆
- 云数据库产品及架构设计背后的考量
- attr()和prop()的区别
- 发顶会论文,怎么就那么难?
- Pandas项目实战1——好莱坞百万级电影评论数据分析
热门文章
- Linux环境下安装SVN
- 分享一个Atmega128L单片机在IAR for AVR中的串口1收发数据的例程
- C# WinForm中NotifyICon控件的用法
- FlashFXP连接失败(连接已拒绝)及530 permission denied(连接已被客户端关闭)
- Niagara Networks网络安全出口解决方案
- 反弹c语言作业,C语言实现反弹球游戏
- Android动态生成答题卡,手机扫描答题卡改卷的最佳选择——ZipGrade
- 电脑中病毒了一直下载安装软件怎么办?
- 三国群雄传ol服务器 修改,三国群英传OL DATA.PAK相关修改
- DAY1——sql 建表/插入数据