[Spring实战系列](9)装配集合

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/50634498 前两篇文章中,我们已经了解了如何使用Spring 配置简单属性值(使用value 属性)和引用其他Bean 的属性(使用ref 属性)。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/50634498
前两篇文章中,我们已经了解了如何使用Spring  配置简单属性值(使用 value 属性)和 引用其他Bean 的属性(使用 ref 属性)。但是value 和ref 仅在Bean 的属性值是单个值的情况下才有用。当Bean 的属性值是集合,Spring 该如何配置呢?

当配置集合类型的Bean属性时,Spring 提供了4 种类型的集合配置元素。


集合元素 用途
<list> 装配list类型的值,允许重复
<set> 装配set类型的值,不允许重复
<map> 装配map类型的值,名称和值可以使任意类型
<props> 装配properties类型的值,名称和值必须都是String类型


当装配类型为数组或者java.util.Collection 任意实现的属性时,<list>和<set> 元素非常有用。我们很快就会看到,其实属性实际定义的集合类型与选择<list> 或者<set> 元素没有任何关系。如果属性为任意的java.util.Collection类型时,这两个配置元素在使用时几乎可以完全互换。


<map> 和<props> 这两个元素分别对应java.util.Map 和java.util.Properties。当我们需要由键- 值对组成的集合时,这两种配置元素非常有用。关键区别在于,<props> 要求键和值都必须为String 类型,而<map> 允许键和值可以是任意类型



1. 装配Set和List


为了展示在Spring 中装配集合,让我们使用如下书店的例子。

 
  
package com.sjf.bean;
/**
* book实体类
* @author Administrator
*
*/
public class Book {
private String name;
private String author;
private double price;
public void setName(String name) {
this.name = name;
}
 
public void setAuthor(String author) {
this.author = author;
}
 
public void setPrice(double price) {
this.price = price;
}
 
@Override
public String toString() {
return "name:" + name + " author:" + author + " price:" + price;
}
}

 
  
package com.sjf.bean;
 
import java.util.Collection;
/**
* Bookstore实体类
* @author Administrator
*
*/
public class Bookstore {
private String name;
private Collection<Book> books;
public void setName(String name) {
this.name = name;
}
public void setBooks(Collection<Book> books) {
this.books = books;
}
public void listAllBook(){
System.out.println("[" + name + "]共存储一下书籍:");
for(Book book : books){
System.out.println(book.toString());
}//for
}
}

在这里最重要的是通过setBooks() 方法注入书籍(book)的集合。


让我们使用<list> 配置元素,为Bookstore赋予所拥有的书籍集合:

 
  
<bean id = "china-pub" class = "com.sjf.bean.Bookstore">
<property name="name" value="china-pub"/>
<property name="books">
<list>
<ref bean="spring"/>
<ref bean="spark"/>
<ref bean="java"/>
</list>
</property>
</bean>
<bean id = "spring" class = "com.sjf.bean.Book">
<property name="name" value = "Spring实战"/>
<property name="author" value="Craig Walls"/>
<property name="price" value="59.00"/>
</bean>
<bean id = "spark" class = "com.sjf.bean.Book">
<property name="name" value = "Spark大数据处理技术"/>
<property name="author" value="夏俊鸾"/>
<property name="price" value="65.00"/>
</bean>
<bean id = "java" class = "com.sjf.bean.Book">
<property name="name" value = "写给大忙人看的Java SE 8"/>
<property name="author" value="Cay S. Horstmann"/>
<property name="price" value="59.00"/>
</bean>

<list> 元素包含一个或多个值。这里的<ref> 元素用来定义Spring 上下文中的其他Bean 引用。当然还可以使用其他的Spring 设值元素作为<list> 的成员,包括<value>、<bean> 和<null/>。实际上,<list> 可以包含另外一个<list> 作为其成员,形成多维列表


运行结果:

 
  
[china-pub]共存储一下书籍:
name:Spring实战 author:Craig Walls price:59.0
name:Spark大数据处理技术 author:夏俊鸾 price:65.0
name:写给大忙人看的Java SE 8 author:Cay S. Horstmann price:59.0

如果Bean 的属性类型为 数组类型java.util.Collection 接口的任意实现(List等),都可以使用<list> 元素。换句话说,即使像下面那样配置books属性,<list> 元素也一样有效:
 
   
private List<Book> books;
或者
 
   
private Book[] books;

同样,也可以使用 <set> 元素来装配 集合类型或者数组类型的属性:

 
  
<bean id = "china-pub" class = "com.sjf.bean.Bookstore">
<property name="name" value="china-pub"/>
<property name="books">
<set>
<ref bean="spring"/>
<ref bean="spark"/>
<ref bean="java"/>
</set>
</property>
</bean>

无论<list> 还是<set> 都可以用来装配类型为java.util.Collection的任意实现或者数组的属性。不能因为属性为java.util.Set 类型,就表示用户必须使用<set> 元素来完成装配。使用<set> 元素配置java.util.List 类型的属性,虽然看起来有点怪怪的,但是这的确是可以的。如果真这样的做话,就需要确保List 中的每一个成员都必须是唯一的。


2. 装配Map


 
  
package com.sjf.bean;
 
import java.util.Map;
/**
* Bookstore实体类
* @author Administrator
*
*/
public class Bookstore {
private String name;
private Map<String,Book> books;
public void setName(String name) {
this.name = name;
}
public void setBooks(Map<String,Book> books) {
this.books = books;
}
public void listAllBook(){
System.out.println("[" + name + "]共存储一下书籍:");
for(String key : books.keySet()){
System.out.println(key + "->" + books.get(key).toString());
}//for
}
}
books属性为java.util.Map 类型,Map 元素的键为String 类型,值为Book类型。因为Map 的成员是由键-值对构成的,当装配该属性时,简单的<list> 或者<set> 配置元素都无法胜任。


下面我们使用map配置books属性:

 
  
<bean id = "china-pub" class = "com.sjf.bean.Bookstore">
<property name="name" value="china-pub"/>
<property name="books">
<map>
<entry key="spring" value-ref="spring in action"/>
<entry key="spark" value-ref="spark in action"/>
<entry key="java" value-ref="java for busy"/>
</map>
</property>
</bean>
<bean id = "spring in action" class = "com.sjf.bean.Book">
<property name="name" value = "Spring实战"/>
<property name="author" value="Craig Walls"/>
<property name="price" value="59.00"/>
</bean>
<bean id = "spark in action" class = "com.sjf.bean.Book">
<property name="name" value = "Spark大数据处理技术"/>
<property name="author" value="夏俊鸾"/>
<property name="price" value="65.00"/>
</bean>
<bean id = "java for busy" class = "com.sjf.bean.Book">
<property name="name" value = "写给大忙人看的Java SE 8"/>
<property name="author" value="Cay S. Horstmann"/>
<property name="price" value="59.00"/>
</bean>
<map> 元素声明了一个java.util.Map 类型的值。每个 <entry> 元素定义Map 的一个成员。在前边的示例中, key 属性指定了entry 的键,而 value-ref属性定义了entry 的值,并引用了Spring 上下文中的其他Bean。

运行结果:
 
    
[china-pub]共存储一下书籍:
spring->nameSpring实战 authorCraig Walls price59.0
spark->nameSpark大数据处理技术 author:夏俊鸾 price65.0
java->name:写给大忙人看的Java SE 8 authorCay S. Horstmann price59.0

尽管在我们的示例中,使用key 属性来指定String 类型的键,使用valueref属性来指定引用类型的值,但实际上,<entry> 元素共有四个属性,分别可以用来指定entry 的键和值:
属性 用途
Key 指定map中entry的键为String。
Key-ref 指定map中entry的键为Spring上下文中其他Bean的引用。
Value 指定map中entry的值为String。
Value-ref 指定map中entry的值为Spring上下文中其他Bean的引用。

程序地址:https://github.com/sjf0115/springdemo-map/tree/master/springdemo-injection


3. 装配properties集合


上面实例中books属性声明为Map 类型,我们用到了value-ref指定每一个entry 的值。这是因为每一个entry 最终都会成为Spring 上下文中的一个Bean。但是如果所配置Map 的每一个entry 的键和值都为String 类型时,我们可以考虑使用java.util.Properties 代替Map。Properties 类提供了和Map 大致相同的功能,但是它限定键和值必须为String 类型


 
  
package com.sjf.bean;
 
import java.util.Properties;
 
/**
* Bookstore实体类
* @author Administrator
*
*/
public class Bookstore {
private String name;
private Properties books;
public void setName(String name) {
this.name = name;
}
public void setBooks(Properties books) {
this.books = books;
}
public void listAllBook(){
System.out.println("[" + name + "]共存储一下书籍:");
for(Object key : books.keySet()){
System.out.println(key + "->" + books.get(key).toString());
}//for
}
}
下面我们使用property配置books属性:
 
   
<bean id = "china-pub" class = "com.sjf.bean.Bookstore">
<property name="name" value="china-pub"/>
<property name="books">
<props>
<prop key="spring in action" >Spring实战</prop>
<prop key="spark in action" >Spark大数据处理技术</prop>
<prop key="java for busy" >写给大忙人看的Java SE 8</prop>
</props>
</property>
</bean>

<props> 元素构建了一个java.util.Properties 值, 这个Properties的每一个成员都由 <prop> 元素定义。每一个<prop> 元素都有一个 key 属性,其定义了Properties 每个成员的键,而每一个成员的值由<prop> 元素的内容所定义。 <property> 元素用于把值或Bean 引用注入到Bean 的属性中;<props> 元素用于定义一个java.util.Properties 类型的集合值; <prop> 元素用于定义<props> 集合的一个成员



参考:《Spring实战》



相关实践学习
简单用户画像分析
本场景主要介绍基于海量日志数据进行简单用户画像分析为背景,如何通过使用DataWorks完成数据采集 、加工数据、配置数据质量监控和数据可视化展现等任务。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
1月前
|
XML Java 数据库连接
spring boot 参数的过滤注解与实战
在Spring Boot应用中,对于入参的过滤,通常会涉及到对Web层的数据验证和处理。Spring Boot借助Spring框架提供了强大的验证框架支持,主要基于JSR-303/JSR-380(Bean Validation API)规范,以及Spring自身的@Valid或@Validated注解来实现请求参数的验证。以下是一些常见的使用案例来展示如何对参数进行过滤和验证。
29 1
|
2月前
|
Dubbo Java 应用服务中间件
实战指南:如何在Spring Boot中无缝整合Dubbo【四】
实战指南:如何在Spring Boot中无缝整合Dubbo【四】
45 0
|
1月前
|
人工智能 JSON 前端开发
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
|
2月前
|
消息中间件 安全 druid
GitHub昙花一现!《Spring Boot趣味实战课》神作开源几分钟被下架
今天给大家分享好书了:刘水镜老师的 《Spring Boot趣味实战课》,网上依旧是没有开源版本!小编会在文末附电子版免费下载方式。 刘水镜是谁? 十余年持续技术文章输出,CSDN博客专家。2020年《 Spring Boot趣味私房课》专栏上线,凭借风趣幽默、深入浅出的写作风格深受读者好评。 《Spring Boot趣味实战课》 内容丰富、趣味实战是本书的两大特色 涵盖 Spring MVC、MyBatis Plus、Spring DaJPA、Spring Security、Quartz等主流框架 整合MySQL. Druid、Redis、 RabbitMQ、Elastics
39 0
|
26天前
|
安全 Java 数据安全/隐私保护
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
57 1
|
2月前
|
设计模式 前端开发 Java
玩转Spring—Spring5新特性之Reactive响应式编程实战
玩转Spring—Spring5新特性之Reactive响应式编程实战
59 0
|
2月前
|
消息中间件 NoSQL Java
Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】
Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】
208 1
|
26天前
|
存储 XML 缓存
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南(一)
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南
60 0
|
2月前
|
监控 IDE Java
Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase()解决大小写不一致问题
Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase()解决大小写不一致问题
42 0
|
12天前
|
Java 数据库 Spring
切面编程的艺术:Spring动态代理解析与实战
切面编程的艺术:Spring动态代理解析与实战
25 0
切面编程的艺术:Spring动态代理解析与实战