在看项目的 Spring 配置文件时, 发现消息队列的配置采用了继承方式配置 Bean, 在这梳理总结一下.
其实在基于 spring 框架开发的项目中, 如果有多个 bean 都是一个类的实例, 如配置多个数据源时, 大部分配置的属性都一样, 只有少部分不一样. 这样的话在配置文件中可以配置和对象一样进行继承.
例如
- <bean id="testParent" abstract="true" class="com.bean.TestBean">
- <property name="param1" value="父参数 1"/>
- <property name="param2" value="父参数 2"/>
- </bean>
- <bean id="testBeanChild1" parent="testParent"/>
- <bean id="testBeanChild2" parent="testParent">
- <property name="param1" value="子参数 1"/>
- </bean>
其中 abstract="true" 的配置表示: 此类在 Spring 容器中不会生成实例.
parent="testBeanParent" 代表子类继承了 testBeanParent, 会生成具体实例, 在子类 Bean 中配置会覆盖父类对应的属性.
在博主项目中遇到场景是这样的:
在 Spring 配置文件中配置消息队列中消费者的实现类, 但其实每个消费者仅仅有个几个属性不相同, 为了避免代码冗余, 修改和可扩展, 采用了上述的方式进行配置.
配置如下:
order-task-comsumer.xml
父类中将消息队列所以要的各种 key 和 url 配置全, 子类仅仅只有几个属性不同.
如果以后非淘平台的业务膨胀了, 仅仅只要在配置文件中拆出部分, 很方便.
- <!-- 自动下单任务监听 -->
- <bean id="abstractAutoFetchOrderTaskMessageListener" abstract="true" class="com.foonsu.erp.orderpool.listeners.AutoFetchOrderTaskMessageListener">
- <property name="accessKey" value="${taobao.appKey}" />
- <property name="secretKey" value="${taobao.appSecret}" />
- <property name="onsChannel" value="${mq.erp_orderpool.autoFetchOrder.onsChannel}" />
- <property name="messageModel" value="${mq.erp_orderpool.autoFetchOrder.messageModel}" />
- <property name="topic" value="${mq.erp_orderpool.autoFetchOrder.topic}" />
- <property name="messageOrder" value="${mq.erp_orderpool.autoFetchOrder.messageOrder}" />
- <property name="orderPoolTaskHandlers" ref="orderPoolTaskHandlersMap"/>
- </bean>
- <!-- 消费淘宝平台消息的消费者 -->
- <bean id="taobaoAutoFetchOrderTaskMessageListener" parent="abstractAutoFetchOrderTaskMessageListener">
- <property name="consumerId" value="${mq.erp_orderpool.autoFetchOrder.taobaoConsumerId}" />
- <property name="subExpression" value="${mq.erp_orderpool.autoFetchOrder.taobaoSubExpression}" />
- <property name="consumeThreadNums" value="${mq.erp_orderpool.autoFetchOrder.taobaoConsumeThreadNums}" />
- </bean>
- <!-- 消费非淘宝平台消息的消费者 -->
- <bean id="otherAutoFetchOrderTaskMessageListener" parent="abstractAutoFetchOrderTaskMessageListener">
- <property name="consumerId" value="${mq.erp_orderpool.autoFetchOrder.otherConsumerId}" />
- <property name="subExpression" value="${mq.erp_orderpool.autoFetchOrder.otherSubExpression}" />
- <property name="consumeThreadNums" value="${mq.erp_orderpool.autoFetchOrder.otherConsumeThreadNums}" />
- </bean>
- <bean id="orderPoolTaskHandlersMap" class="java.util.HashMap">
- <constructor-arg>
- <map>
- <entry key="01" value-ref="taoBaoOrderTaskHandler" />
- <entry key="05" value-ref="jdOrderTaskHandler" />
- <entry key="25" value-ref="dadangjiaOrderTaskHandler" />
- <entry key="16" value-ref="pddOrderTaskHandler" />
- <entry key="13" value-ref="alibabaOrderTaskHandler" />
- </map>
- </constructor-arg>
- </bean>
ps:&{XXX} 配置中类似这样的符号表示是从 properties 文件中读取需要的配置, Spring 加载的时候会替换.
- alibaba.properties
- alibaba.appKey=7151192
- alibaba.appSecret=vLCR5tk0D5u7
- alibaba.dataUrl=http://gw.open.1688.com/openapi/
- alibaba.accessTokenUrl=https://gw.open.1688.com/openapi/http/1/system.oauth2/getToken/7151192
- alibaba.refreshTokenUrl=https://gw.open.1688.com/openapi/param2/1/system.oauth2/getToken/7151192
- alibaba.logisticsCompanyCodeMapStr=01\=SF,\u987a\u4e30|02\=EMS,EMS|03\=STO,\u7533\u901a|04\=HTKY,\u767e\u4e16\u5feb\u9012|05\=YTO,\u5706\u901a|06\=ZTO,\u4e2d\u901a|07\=YUNDA,\u97f5\u8fbe|08\=EYB,EMS\u7ecf\u6d4e\u5feb\u9012|09\=ZJS,\u5b85\u6025\u9001|10\=OTHER,\u5176\u5b83|11\=UC,\u4f18\u901f|12\=TTKDEX,\u5929\u5929|13\=QFKD,\u5168\u5cf0\u5feb\u9012|14\=FAST,\u5feb\u6377\u901f\u9012|15\=POSTB,\u90ae\u653f\u56fd\u5185\u5c0f\u5305|16\=GTO,\u56fd\u901a\u5feb\u9012|17\=DBKD,\u5fb7\u90a6\u5feb\u9012|18\=EMS,EMS|19\=OTHER,\u5176\u5b83|20\=OTHER,\u5176\u5b83|21\=ANE56,\u5b89\u80fd\u7269\u6d41|22\=OTHER,\u5176\u5b83|23\=OTHER,\u5176\u5b83|24\=SURE,\u901f\u5c14|25\=OTHER,\u5176\u5b83
来源: http://www.bubuko.com/infodetail-2690562.html