博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Srping - bean的依赖注入(Dependency injection)
阅读量:6884 次
发布时间:2019-06-27

本文共 5237 字,大约阅读时间需要 17 分钟。

目录


   

   

   

   

   

   

   

   

   

   

   

 

1 概述


这篇文章主要就是讲解Springbean之间依赖注入的方法,本文不讲原理,只涉及用法。 

在实际项目中,我们常常需要在一个bean中引用另外一个bean,例如业务逻辑处理(service)层调用数据处理(dao)层。那么就有了依赖注入(Dependency Injection),简称DI

 

2 两种基本的依赖注入方式


Spring提供了2种基本方式让我们实现DI,分别是通过构造函数和setter方法。下面我们来一一介绍。

 

2.1 构造函数方式

实现方式如下:

java代码:

package x.y;public class Foo {    public Foo(Bar bar, Baz baz) {        // ...    }}

bean配置:

Spring会检查bean之间的依赖关系,会先加载(初始化)被依赖的bean,在例子中,barbaz首先被加载,然后通过构造函数参数的形式注入到foo中。相信这个很好理解吧。

除了支持bean的注入之外,Spring还支持常量的注入,如下:

其中constructor-arg需要根据构造函数的顺序对应好(参数类型要匹配)。

除了默认的顺序排序,我们还可以指定Index属性,来指定constructor-arg对应构造函数参数的位置:

另外还可以指定参数名称来对应指定构造函数参数,但是这种方式需要给类的构造函数加上 注解

package examples;public class ExampleBean {    // Fields omitted    @ConstructorProperties({"years", "ultimateAnswer"})    public ExampleBean(int years, String ultimateAnswer) {        this.years = years;        this.ultimateAnswer = ultimateAnswer;    }}

2.2 Setter方式

实现方式如下:

java代码:

public class ExampleBean {    private AnotherBean beanOne;    private YetAnotherBean beanTwo;    private int i;        public void setBeanOne(AnotherBean beanOne) {        this.beanOne = beanOne;    }        public void setBeanTwo(YetAnotherBean beanTwo) {        this.beanTwo = beanTwo;    }        public void setIntegerProperty(int i) {        this.i = i;    }}

bean配置:

Spring在实例化bean之后,会将配置中property属性通过对应的setter方法将被引用对象设置到bean的属性中。同样的,被引用的bean会先于引用beanSpring加载实例化。

属性的setter方法需要遵循java的标准,即set + 属性名(首字母改为大写)。

在上面例子中

<property name="beanTwo" ref="yetAnotherBean"/>

还可以写成:

<property name="beanTwo"/> 

    <idref bean="yetAnotherBean"/> 

</property> 

或者:

<property name="beanTwo" value="yetAnotherBean"/>

通过<idref/>标签,Spring会去查找容器中ID为指定值的bean。

 

3 其他依赖注入功能


3.1 <ref/>标签引用不同范围的bean

之前我们所看到的例子都是bean引用了同一个Spring容器中的bean,Spring还支持bean引用同个XML配置文件中的bean,或者是父容器的bean。写法分别是:

引用当前容器中的bean

<ref bean="someBean"/>

引用父容器中的bean

<ref parent="someBean"/>

引用当前XML中的bean

<ref local="someBean"/>

 

3.2 内部bean

内部bean指的是在某个bean内部配置的bean。配置方式如下:

内部bean可以不用的idname属性

3.3 集合注入

除了注入基础类型和bean之外,我们还可以对bean中的集合属性进行注入,ListSetMapProperties分别对应配置中的<list/><set/><map/><props/>标签,配置方式如下:

 

administrator@example.org
support@example.org
development@example.org
a list element followed by a reference
just some string

3.4 集合合并

假设我们有一个bean collectionParent,collectionParent里有个Properties类型的属性config:

localhost
8080

这时,因为业务需要,我们可能有多种场景,需要用到不同的config,或者内容更多的config,假设port属性改了,而且需要多一个protocol属性,那么我们可以这么做:

http
9090

collectionChild的配置通过parent属性继承collectionParent,再在config的props标签中加入merge="true"的属性,就可以实现将collectionParent中config的配置合并过来。

实例化后collectionParent的config属性是{port=8080, url=localhost}

collectionChild的config属性是{port=9090, url=localhost, protocol=http}

注意,重复的元素会被覆盖。

这里用的是Properties作为例子,同样的ListMapSet也可以,但是对于List略有不同,List是以链表形式出现的,是有序的,2List合并成1List后,parent List的元素肯定在child List元素之前。

不同类型的集合之间不能合并,否则Spring会抛出异常。

 

3.5 强类型集合注入

假设我们的bean 类中属性定义的是一个强类型的集合如Map<Sring, Fload>Spring同样支持注入:

public class Foo {    private Map
accounts; public void setAccounts(Map
accounts) { this.accounts = accounts; }}

 

例中的9.992.753.99在注入属性前Spring会自动做类型转换,例子中转为Float类型。

 

3.6 null和空字符串

这个比较简单,没什么好说的,看例子:

空字符串:

<bean class="ExampleBean">

  <property name="email" value=""/>
</bean>

null

<bean class="ExampleBean">

  <property name="email"><null/></property>
</bean>

 

3.7 p-namespace方式配置属性注入

p-namespace方式是用于替换<property/>标签的另外一种简洁的写法,通常我们给一个bean注入属性是这么写的:

在Spring 2.0之后,我们可以这么写:

如果我们的bean的属性引用了其他bean,我们可以这么写:

p:spouse-ref中spouse是属性的名称,-ref表示引用了其他bean。

但是在实际项目中,我们还是需要保证所有配置使用一种风格,要么<property/>要么p-namespace格式。

 

3.8 c-namespace方式配置构造函数参数注入

c-namespace方式是用于替换<constructor-arg/>标签的另外一种写法,通常定义一个bean的构造函数的参数是这么写的:

通过c-namespace我们可以这么写:

写法和p-namespace类似,也就把p换成c而已。

3.9 嵌套属性注入

假设bean中有个属性A,属性A里有个属性B,那么我们也可以通过配置给A.B赋值:

需要注意的是,父属性不能为空,如例子中 fred不能为nullfred.bob也不能为null,否则在注入的时候会抛出空指针异常。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/ViviChan/p/4981443.html

你可能感兴趣的文章
卷积的数学意义及信号学应用
查看>>
docker之数据卷管理
查看>>
[Vijos] 遭遇战
查看>>
UVA1203 Argus
查看>>
React 性能调优总结
查看>>
CF860E Arkady and a Nobody-men
查看>>
QTREE5 - Query on a tree V——LCT
查看>>
Linux 下Shell 脚本几种基本命令替换区别
查看>>
tcp长连接分包方法
查看>>
linux中使用mysql数据库
查看>>
E - 白银 CSU - 1726: 你经历过绝望吗?两次! 搜索
查看>>
探索Windows 8.1 Update 新功能点
查看>>
RabbitMQctl命令
查看>>
小程序-轮播图案例
查看>>
2019北航OO第一单元作业总结
查看>>
例子 新闻发布
查看>>
java编程规范
查看>>
使同一个server上不同port的django应用可在同一个浏览器上打开
查看>>
hdu 1002 A + B Problem II
查看>>
10.2 io流 之字节流和字符流
查看>>