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

本文涉及的产品
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 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实战》



相关实践学习
基于MaxCompute的热门话题分析
Apsara Clouder大数据专项技能认证配套课程:基于MaxCompute的热门话题分析
目录
相关文章
|
1月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
321 3
|
4月前
|
人工智能 Java API
Spring AI 实战|Spring AI入门之DeepSeek调用
本文介绍了Spring AI框架如何帮助Java开发者轻松集成和使用大模型API。文章从Spring AI的初探开始,探讨了其核心能力及应用场景,包括手动与自动发起请求、流式响应实现打字机效果,以及兼容不同AI服务(如DeepSeek、通义千问)的方法。同时,还详细讲解了如何在生产环境中添加监控以优化性能和成本管理。通过Spring AI,开发者可以简化大模型调用流程,降低复杂度,为企业智能应用开发提供强大支持。最后,文章展望了Spring AI在未来AI时代的重要作用,鼓励开发者积极拥抱这一技术变革。
1593 71
Spring AI 实战|Spring AI入门之DeepSeek调用
|
1月前
|
人工智能 监控 安全
如何快速上手【Spring AOP】?核心应用实战(上篇)
哈喽大家好吖~欢迎来到Spring AOP系列教程的上篇 - 应用篇。在本篇,我们将专注于Spring AOP的实际应用,通过具体的代码示例和场景分析,帮助大家掌握AOP的使用方法和技巧。而在后续的下篇中,我们将深入探讨Spring AOP的实现原理和底层机制。 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心特性之一,它能够帮助我们解决横切关注点(如日志记录、性能统计、安全控制、事务管理等)的问题,提高代码的模块化程度和复用性。
|
5月前
|
安全 Java 数据库
Spring Security 实战指南:从入门到精通
本文详细介绍了Spring Security在Java Web项目中的应用,涵盖登录、权限控制与安全防护等功能。通过Filter Chain过滤器链实现请求拦截与认证授权,核心组件包括AuthenticationProvider和UserDetailsService,负责用户信息加载与密码验证。文章还解析了项目结构,如SecurityConfig配置类、User实体类及自定义登录逻辑,并探讨了Method-Level Security、CSRF防护、Remember-Me等进阶功能。最后总结了Spring Security的核心机制与常见配置,帮助开发者构建健壮的安全系统。
332 0
|
3月前
|
Cloud Native Java 微服务
Spring Boot 3.x 现代化应用开发实战技巧与最佳实践
本指南基于Spring Boot 3.x,融合微服务、云原生与响应式编程等前沿技术,打造现代化应用开发实践。通过构建智能电商平台案例,涵盖商品、订单、用户等核心服务,展示Spring WebFlux、OAuth 2.0认证、Spring Cloud Gateway路由、GraalVM原生编译等技术实现。同时提供Docker/Kubernetes部署方案及性能优化策略,助您掌握从开发到生产的全流程。代码示例详实,适合进阶开发者参考。
341 2
|
5月前
|
存储 人工智能 Java
Spring AI与DeepSeek实战四:系统API调用
在AI应用开发中,工具调用是增强大模型能力的核心技术,通过让模型与外部API或工具交互,可实现实时信息检索(如天气查询、新闻获取)、系统操作(如创建任务、发送邮件)等功能;本文结合Spring AI与大模型,演示如何通过Tool Calling实现系统API调用,同时处理多轮对话中的会话记忆。
1017 57
|
2月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
728 0
|
6月前
|
前端开发 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 介绍
本课介绍Spring Boot集成Thymeleaf模板引擎。Thymeleaf是一款现代服务器端Java模板引擎,支持Web和独立环境,可实现自然模板开发,便于团队协作。与传统JSP不同,Thymeleaf模板可以直接在浏览器中打开,方便前端人员查看静态原型。通过在HTML标签中添加扩展属性(如`th:text`),Thymeleaf能够在服务运行时动态替换内容,展示数据库中的数据,同时兼容静态页面展示,为开发带来灵活性和便利性。
297 0
|
2月前
|
缓存 JSON 前端开发
第07课:Spring Boot集成Thymeleaf模板引擎
第07课:Spring Boot集成Thymeleaf模板引擎
373 0
第07课:Spring Boot集成Thymeleaf模板引擎

热门文章

最新文章