Spring util 命名空间详解

Spring util 命名空间详解

一、util 命名空间是什么?

util 命名空间是 Spring 提供的一个 XML 扩展命名空间,专门用于定义集合类型的 Bean。它解决了标准 XML 配置中集合无法独立定义、无法被多个 Bean 复用的问题。

在没有 util 命名空间时,集合只能内联在某个 Bean 的 <property> 中:

xml 复制代码
<bean id="userService" class="com.example.UserService">
    <property name="servers">
        <list>
            <value>server1</value>
            <value>server2</value>
        </list>
    </property>
</bean>

这个 List 只属于 userService,其他 Bean 无法引用它。如果多个 Bean 需要同一个集合,只能重复配置。

util 命名空间允许把集合定义成独立的 Bean,赋予 id,然后通过 ref 注入到任意 Bean 中。

xml 复制代码
<util:list id="serverList">
    <value>server1</value>
    <value>server2</value>
</util:list>

<bean id="userService" class="com.example.UserService">
    <property name="servers" ref="serverList"/>
</bean>

<bean id="orderService" class="com.example.OrderService">
    <property name="servers" ref="serverList"/>
</bean>

serverList 成为一个独立的 Bean,可以被多个 Bean 共享。

二、引入 util 命名空间

在 XML 根元素中声明:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/util
           http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- util 标签在这里使用 -->

</beans>

关键是 xmlns:utilspring-util.xsd 两行。没有它们,<util:list> 等标签不会被解析。

三、常用标签详解

3.1 <util:list> 定义 List Bean

xml 复制代码
<util:list id="serverList" list-class="java.util.ArrayList">
    <value>server1</value>
    <value>server2</value>
    <value>server3</value>
</util:list>

list-class 可选,默认是 ArrayList。如果需要 LinkedList,可以指定:

xml 复制代码
<util:list id="serverList" list-class="java.util.LinkedList">

List 中可以放简单值、Bean 引用、嵌套集合。

xml 复制代码
<util:list id="mixedList">
    <value>text</value>
    <ref bean="userDao"/>
    <bean class="com.example.User"/>
</util:list>

3.2 <util:set> 定义 Set Bean

xml 复制代码
<util:set id="serverSet" set-class="java.util.LinkedHashSet">
    <value>server1</value>
    <value>server2</value>
    <value>server1</value>  <!-- 自动去重 -->
</util:set>

set-class 可选,默认是 LinkedHashSet。Set 会自动去重,元素顺序取决于实现类。

3.3 <util:map> 定义 Map Bean

xml 复制代码
<util:map id="configMap" map-class="java.util.LinkedHashMap">
    <entry key="timeout" value="30"/>
    <entry key="retry" value="3"/>
    <entry key="debug" value="true"/>
</util:map>

map-class 可选,默认是 LinkedHashMap。entry 的 key 和 value 可以是简单值、Bean 引用、嵌套对象。

xml 复制代码
<util:map id="beanMap">
    <entry key="primary" value-ref="primaryDataSource"/>
    <entry key="secondary" value-ref="secondaryDataSource"/>
</util:map>

3.4 <util:properties> 定义 Properties Bean

方式一:从外部文件加载

xml 复制代码
<util:properties id="dbProps" location="classpath:db.properties"/>

方式二:内联定义

xml 复制代码
<util:properties id="appProps">
    <prop key="app.name">myapp</prop>
    <prop key="app.timeout">30</prop>
</util:properties>

<util:properties> 返回的是 java.util.Properties 对象,键和值都是 String。

3.5 <util:constant> 引用静态常量

xml 复制代码
<util:constant id="maxValue" static-field="java.lang.Integer.MAX_VALUE"/>
<util:constant id="charset" static-field="java.nio.charset.StandardCharsets.UTF_8"/>

static-field 写全限定类名加字段名。常用于把某个静态常量注册为 Bean。

3.6 <util:property-path> 引用其他 Bean 的属性

xml 复制代码
<bean id="user" class="com.example.User">
    <property name="name" value="张三"/>
</bean>

<util:property-path id="userName" path="user.name"/>

userName 成为一个 Bean,值是 username 属性。常用于把某个 Bean 的属性暴露为独立的 Bean。

四、与标准集合标签的区别

对比维度 util 命名空间 标准 <list><map>
是否独立 Bean 是,有 id 否,内联在属性中
是否可复用 可被多个 Bean 引用 只属于当前 Bean
是否可单独获取 可以,getBean("id") 不可以
定义位置 直接放在 <beans> 嵌套在 <property><constructor-arg>
适用场景 多个 Bean 共享集合 单个 Bean 的私有集合

五、与 p 命名空间配合

p 命名空间不能直接定义集合,但可以引用 util 定义的集合 Bean。

xml 复制代码
<util:list id="serverList">
    <value>server1</value>
    <value>server2</value>
</util:list>

<bean id="userService" class="com.example.UserService"
      p:servers-ref="serverList"
      p:appName="myapp"/>

这种组合在 XML 配置时代很常见:util 负责定义集合,p 负责注入。

六、底层原理

util 命名空间的解析由 UtilNamespaceHandler 完成,它注册了以下 BeanDefinitionParser

标签 解析器
<util:list> ListBeanDefinitionParser
<util:set> SetBeanDefinitionParser
<util:map> MapBeanDefinitionParser
<util:properties> PropertiesBeanDefinitionParser
<util:constant> ConstantBeanDefinitionParser
<util:property-path> PropertyPathBeanDefinitionParser

<util:list> 为例,解析器会创建一个 ListFactoryBean 的 BeanDefinition,把 list-classvalueref 等配置转换为 ListFactoryBean 的属性。容器实例化时,ListFactoryBeangetObject() 返回实际的 List 对象。

所以 util 定义的集合本质上是工厂 Bean 生产的产品,而不是直接注册的集合对象。

七、完整示例

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/util
           http://www.springframework.org/schema/util/spring-util.xsd">

    <util:list id="serverList" list-class="java.util.ArrayList">
        <value>server1.example.com</value>
        <value>server2.example.com</value>
        <value>server3.example.com</value>
    </util:list>

    <util:set id="roleSet">
        <value>admin</value>
        <value>user</value>
        <value>admin</value>
    </util:set>

    <util:map id="configMap">
        <entry key="timeout" value="30"/>
        <entry key="retry" value="3"/>
    </util:map>

    <util:properties id="appProps">
        <prop key="app.name">myapp</prop>
        <prop key="app.version">1.0</prop>
    </util:properties>

    <bean id="userService" class="com.example.UserService"
          p:servers-ref="serverList"
          p:roles-ref="roleSet"
          p:configs-ref="configMap"
          p:props-ref="appProps"/>

</beans>

Java 类:

java 复制代码
public class UserService {
    private List<String> servers;
    private Set<String> roles;
    private Map<String, String> configs;
    private Properties props;
    
    // setter 方法
    public void setServers(List<String> servers) { this.servers = servers; }
    public void setRoles(Set<String> roles) { this.roles = roles; }
    public void setConfigs(Map<String, String> configs) { this.configs = configs; }
    public void setProps(Properties props) { this.props = props; }
}

八、注意事项

1. 需要声明 util 命名空间和 schemaLocation

缺少 xmlns:utilspring-util.xsd,标签不会被解析。

2. id 必须唯一

util 定义的集合是独立 Bean,id 不能与其他 Bean 重复。

3. 集合元素类型

<value> 默认是 String,Spring 会尝试类型转换。如果集合是 List<Integer>,Spring 会自动把 "30" 转成 30

4. <util:properties> 的 location

加载外部文件时,路径要写对:classpath:db.propertiesfile:/opt/config/db.properties

5. 不支持数组

util 命名空间没有 <util:array>。需要数组时,用 <util:list> 定义 List,注入到数组类型的属性时 Spring 会自动转换。

6. 现代项目中使用减少

Spring Boot 以 Java 配置和注解为主,util 命名空间主要出现在老项目和传统 XML 配置中。理解它有助于维护旧代码。

九、总结

维度 核心要点
作用 定义独立、可复用的集合 Bean
引入 xmlns:util + spring-util.xsd
常用标签 <util:list><util:set><util:map><util:properties><util:constant><util:property-path>
与标准集合区别 util 定义的集合是独立 Bean,可被多个 Bean 引用
与 p 命名空间配合 util 定义集合,p 负责注入
底层 UtilNamespaceHandler + 各标签的 BeanDefinitionParser,本质是工厂 Bean
适用场景 多个 Bean 共享集合、需要单独获取集合 Bean、加载 Properties 文件
注意事项 需要命名空间声明、id 唯一、不支持数组、现代项目使用减少

util 命名空间是 Spring XML 配置时代管理集合 Bean 的标准工具。它让集合从"某个 Bean 的私有属性"变成"容器中可共享的资源",在需要多个 Bean 共用同一组配置或集合时非常有用。虽然在新项目中已经很少直接使用,但阅读和维护老项目时,掌握 util 命名空间能帮你快速理解配置结构。

相关推荐
古法安卓1 小时前
Android-休眠唤醒后onLocationChanged没有数据问题排查
android·java·android studio
打工仔折腾 AI2 小时前
普通摄像头接入AI识别:绿联NAS部署Frigate监控实战
人工智能·后端·python·性能优化·ai agent 实战
周GZ2 小时前
简单讲解线程池的4种拒绝策略
java
白远山2 小时前
24小时自助健身房系统开发实战:从需求分析到完整指南
java·开发语言·数据库·数据挖掘·需求分析
暮雨哀尘2 小时前
JAVA基础练习(四):SpringBoot 实现简易登录功能
java·spring boot·eclipse·maven
光依旧3 小时前
MCP实战手记系列(二):跑通第一个 MCP Server(文末附github源码链接)
java·spring ai·mcp·ai 开发·源码实战
白远山3 小时前
上海24小时自助健身房系统软件开发实战指南:从需求到部署
java·架构·uni-app·需求分析
万物智能4 小时前
SARADC模数转换—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
前端·后端