作者:zyl910

  以往我们想在spring的xml配置文件中增加说明文本时,只能使用xml注释(<!-- 注释 -->)。这对于“调试、部署时想批量屏蔽部分bean”是不利的。于是本文讨论如何解决这个难题,并给出一个对项目配置改动少的方案。

一、最初问题

  例如现在想用quartz管理一个定时器类,故需要先在spring的xml配置文件中把该定时器类(JobTest)配置为bean。一般是这样写——

  1. <!-- 测试Job. -->
  2. <bean id="jobTest" class="org.zyl910.zyllibj.test.spring.JobTest" />

  上面就是利用了xml注释,来存储该bean的说明。虽然清晰,但它占用了xml注释。

  xml规定注释不能嵌套。于是若想批量屏蔽一些bean时,得细心跳过原来的xml注释说明部分,单个单个给注释掉。不但要花很多功夫,且一不小心容易造成xml注释不匹配,整个文件失效。

  故考虑不再使用xml注释来填写说明文本。

二、最初问题的解决办法

  首先尝过在bean标签内直接增加一个特性(attribute)来填写说明,例如——

  1. <bean id="jobTest" class="org.zyl910.zyllibj.test.spring.JobTest" title="测试Job" />

  但是该办法是行不通的。因spring会检查xml标签内的特性,若发现其他特性便会报错退出。于是我们只能另外想办法。

  想到这个bean配的是我们自己的类,故我们可以在自己的类里加一个“title”属性(property),然后在xml里配置该bean的属性。例如——

  1. <bean id="jobTest" class="org.zyl910.zyllibj.test.spring.JobTest">
  2. <property name="title" value="测试Job"/>
  3. </bean>

三、真正难题

  用quartz管理定时器时,除了需配置类的bean外,还需要配置方法、触发器的bean,最后还要配置调度器。例如——

  1. <bean id="jobTest" class="org.zyl910.zyllibj.test.spring.JobTest">
  2. <property name="title" value="测试Job"/>
  3. </bean>
  4. <bean id="jobTest_process" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
  5. <property name="targetObject" ref="jobTest"/>
  6. <property name="targetMethod"><value>process</value></property>
  7. <property name="concurrent" value="false"/>
  8. </bean>
  9. <bean id="jobTest_processTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
  10. <property name="jobDetail" ref="jobTest_process"/>
  11. <property name="cronExpression" value="* 0/1 * * * ?"/>
  12. </bean>
  13. <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  14. <property name="triggers">
  15. <list>
  16. <ref bean="jobTest_processTrigger"/>
  17. </list>
  18. </property>
  19. </bean>

  现在就又存在这样问题——想为“triggers”里的项目增加说明该怎么办?

  因为根据调试、部署需要,triggers里的定时器是经常需要使用xml注释来批量控制启停的。如果用xml注释写说明,就没法批量启停了。

  其次,先前也试过,spring标签里不能加特性(attribute)。

  第三,这里用的是ref标签,故不能像先前对bean标签那样加个属性(property)来解决.

  第四,这里是在list内加定时器,故不能用其他spring标签放其他类型的数据.

  在网上搜索了很久,发现spring支持xml扩展,但该方案不适合我们项目。因为那种方法对项目配置改动较多。而对于大型项目来说,是拆分为许多个子项目,若用spring扩展的话影响太大了,其他子项目不一定同意这样的更改,没法形成统一方案。

四、解决方案

  我对着spring的官方文档、源码看了很久,最终想出来了一套简单有效的解决方案。

  新建一个“TitleProxyFactoryBean”类,它继承自spring的“ProxyFactoryBean”类,并提供title等属性。代码如下——

  1. package org.zyl910.zyllibj.spring;
  2. import org.springframework.aop.framework.ProxyFactoryBean;
  3. /** 带标题的代理Bean工厂.
  4. *
  5. * <p>由于spring的xml里不能直接加特性写注释,且spring的xml扩展机制对项目改动较大. 故制定了此类来实现为bean加说明的功能.</p>
  6. *
  7. * 提供了3个可选属性:
  8. * <ul>
  9. * <li>String title: 标题. 可用于介绍该bean是什么.</li>
  10. * <li>String group: 组. 有时需要对bean进行分组,此时可把分组说明填这里.</li>
  11. * <li>Object tag: 标记. 可用根据需要填充任意内容.</li>
  12. * </ul>
  13. *
  14. * @author zyl910
  15. *
  16. */
  17. public class TitleProxyFactoryBean extends ProxyFactoryBean {
  18. private static final long serialVersionUID = -4213438026061725669L;
  19. /** 标题. 可用于介绍该bean是什么. */
  20. private String title;
  21. /** 组. 有时需要对bean进行分组,此时可把分组说明填这里. */
  22. private String group;
  23. /** 标记. 可用根据需要填充任意内容. */
  24. private Object tag;
  25. /** 取得标题.
  26. * @return the title
  27. */
  28. public String getTitle() {
  29. return title;
  30. }
  31. /** 设置标题.
  32. * @param title the title to set
  33. */
  34. public void setTitle(String title) {
  35. this.title = title;
  36. }
  37. /** 取得组.
  38. * @return the group
  39. */
  40. public String getGroup() {
  41. return group;
  42. }
  43. /** 设置组.
  44. * @param group the group to set
  45. */
  46. public void setGroup(String group) {
  47. this.group = group;
  48. }
  49. /** 取得标记.
  50. * @return the tag
  51. */
  52. public Object getTag() {
  53. return tag;
  54. }
  55. /** 设置标记.
  56. * @param tag the tag to set
  57. */
  58. public void setTag(Object tag) {
  59. this.tag = tag;
  60. }
  61. }

  然后在配置文件中便可以用代理的方式引用bean,并可填写说明。例如——

  1. <bean class="org.zyl910.zyllibj.spring.TitleProxyFactoryBean"><property name="target" ref="jobTest_processTrigger"/><property name="title" value="测试Job"/></bean>

  测试通过。

五、配置优化

  上面的方案虽然能解决问题,但是太长了,不易读。

  此时可做2点改进——

  1. 使用spring的p来配置,它比property标签精简很多。
  2. 将重要属性放在前面,而class等无需改的放后面。

  例如——

  1. <bean p:target-ref="jobTest_processTrigger" p:title="测试Job" class="org.zyl910.zyllibj.spring.TitleProxyFactoryBean" />

  优化后测试通过。

(完)

源码地址: https://coding.net/u/zyl910/p/zyllibj/git

[Java] 解决spring的xml标签内不能自由增加说明的难题,方便调试、部署时进行批量屏蔽的更多相关文章

  1. Java Map转成xml标签字符串

    一个简单的java实现,供参考: package com.trilogy.session.data; import java.lang.reflect.Field; import java.util. ...

  2. spring web.xml 标签<param-name>contextConfigLocation</param-name>

    <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</lis ...

  3. spring自定义xml标签&自定义注解

    public class YafBeanDefinitionParser implements BeanDefinitionParser { private BeanDefinitionRegistr ...

  4. Android项目部署时,发生AndroidRuntime:android.view.InflateException: Binary XML file line #168: Error inflating class错误

    这个错误也是让我纠结了一天,当时写的项目在安卓虚拟机上运行都很正常,于是当我部署到安卓手机上时,点击登陆按钮跳转到用户主界面的时候直接结束运行返回登陆界面.    当时,我仔细检查了一下自己的代码,并 ...

  5. Spring框架 全注解annotation不使用配置文件(SpringConfiguration.java类代替) 补充 xml配置文件没有提示解决

    全注解不使用配置文件 首先还是倒包 在原有的jar包: 需Spring压缩包中的四个核心JAR包 beans .context.core 和expression 下载地址: https://pan.b ...

  6. 6.2 dubbo在spring中自定义xml标签源码解析

    在6.1 如何在spring中自定义xml标签中我们看到了在spring中自定义xml标签的方式.dubbo也是这样来实现的. 一 META_INF/dubbo.xsd 比较长,只列出<dubb ...

  7. spring:使用<prop>标签为Java持久属性集注入值

    spring:使用<prop>标签为Java持久属性集注入值 使用 spring 提供的<prop>为Java持久属性集注入值,也就是向 java.util.Propertie ...

  8. 使用idea搭建maven项目时 java目录下的xml文件没有加载的解决方法

    今天在idea集成开发环境下 使用maven搭建了ssm项目,遇到了3个问题 首先我们先复习一下知识点: 第一步:在web.xml中配置spring监听器 <!-- spring监听器 加载sp ...

  9. java web 加载Spring --web.xml 篇

    spring是目前最流行的框架.今天谈谈对spring的认识 起步 javaweb中我们首先会遇到的配置文件就是web.xml,这是javaweb为我们封装的逻辑,不在今天的研究中.略过,下面是一个标 ...

随机推荐

  1. SQL2008性能计数器注册表配置单元一致性失败

    按照这个操作 http://jingyan.baidu.com/article/7c6fb4287c923880652c9074.html如果在注册表中没有 HKEY_LOCAL_MACHINE\SO ...

  2. @Html.Partials 加载分布视图传参数

    如何在视图中利用 viewData参数和model参数,示例如下 <body> <div style="background:#ffd800;width:200px;pad ...

  3. a:link,a:visited,a:hover,a:active

    1:解释 link:连接平常的状态 visited:连接被访问过之后 hover:鼠标放到连接上的时候 active:连接被按下的时候      详细的: :hover版本:CSS1/CSS2 兼容性 ...

  4. EF常用查询写法

    1.var list = from category in context.category join commodity in context.commodity on category.id eq ...

  5. OkHttp使用进阶 译自OkHttp Github官方教程

    版权声明: 欢迎转载,但请保留文章原始出处 作者:GavinCT 出处:http://www.cnblogs.com/ct2011/p/3997368.html 没有使用过OkHttp的,可以先看Ok ...

  6. javascript改变样式(cssFloat,styleFloat)

    昨天遇到一用js改变元素浮动的,当时直接写了 obj.style.float="left";结果没起作用:查了资料后才发现不能这样写,现在整理下几种样式写法 1,直接写css属性的 ...

  7. [C#] 與Android共舞–手機post資料給Server (转帖)

    最近在搞安卓,跟Server溝通是一定要的,這範例很簡單,就是我在Android 上面,透過POST 的方式傳資料給 Server ,則Server 收到值後直接回傳, Server side 是用a ...

  8. Dynamic CRM 2013学习笔记(四十六)简单审批流的实现

    前面介绍过自定义审批流: Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示 Dynamic CRM 2013学习笔记(二十一)自定义审批流2 - 配置按钮 Dynamic ...

  9. 【Leetcode】【Medium】Set Matrix Zeroes

    Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. 解题思路: ...

  10. Unity3D——物体鼠标跟随转向

    int floorMask; float camRayLenth = 100f;//摄像机射线距离 void Truning() { Ray ray = Camera.main.ScreenPoint ...