如何在beans.xml中定义局部占位符避免重复书写全限定类名
实现方案
Spring原生XML配置不需要自定义标签就能实现类名一次定义、多次复用,既不会污染全局属性命名空间,也不会影响原有全局属性加载,以下是两种可直接落地的方案:
方案1:当前XML内定义短ID的Class类型Bean(推荐)
直接在当前beans.xml中定义一个指向目标类的Class类型Bean,取一个短ID,后续在SpEL中直接引用这个短ID即可访问静态常量,不需要重复写冗长的全限定类名。这个Bean仅在当前Spring配置上下文可见,不会侵入全局属性空间:
<!-- 短名Class Bean,仅当前配置文件内使用 --> <bean id="WC" class="java.lang.Class" factory-method="forName"> <constructor-arg value="com.myapp.longname.verylong.WelcomeController"/> </bean> <util:list id="myFractions" value-type="java.lang.String"> <value>#{ WC.RED_FRACTION }</value> <value>#{ WC.BLUE_FRACTION }</value> <value>#{ WC.GREEN_FRACTION }</value> </util:list>
- 优势:写法比预期的占位符形式更简洁,完全不涉及属性占位符解析逻辑,不存在和全局属性冲突的可能,只要短ID不与其他Bean重名即可正常运行。
方案2:配置局部属性占位符解析器
如果你偏向使用占位符写法,可以为当前XML配置独立的属性解析器,指定不覆盖全局属性、遇到无法解析的占位符时交还给全局解析器处理,就不会出现之前全局属性读取失败的问题:
<!-- 当前XML专用占位符解析器,不影响全局属性加载 --> <context:property-placeholder properties-ref="localFractionProps" local-override="false" ignore-unresolvable="true" order="0"/> <util:properties id="localFractionProps"> <prop key="my.prefix">com.myapp.longname.verylong.WelcomeController</prop> </util:properties> <util:list id="myFractions" value-type="java.lang.String"> <value>#{ T(${my.prefix}).RED_FRACTION }</value> <value>#{ T(${my.prefix}).BLUE_FRACTION }</value> <value>#{ T(${my.prefix}).GREEN_FRACTION }</value> </util:list>
- 之前直接定义
PropertyPlaceholderConfigurer导致全局属性失效的原因:没有开启ignoreUnresolvablePlaceholders配置,自定义解析器优先级高于全局解析器,遇到无法识别的全局属性时直接抛出异常,不会传递给后续全局解析器处理。
注:Spring原生XML配置不提供预期中仅作用于单个
<util:list>块的局部占位符标签,以上两种方案已经是侵入性最低、最接近需求的实现,其中方案1的代码量更少、维护成本更低。
内容的提问来源于stack exchange,提问作者AvrDragon
相关产品推荐
相关产品推荐

