场景:

实际场景中,我们通常会将一类操作定义为xxxHandler,xxxProcessor。这样,我们需要对handler/processor进行统一管理,类似定义一个工厂,可以从工厂中根据type得到实际的handler/processor。

实现1

我一种常用的实现思路是在 每个handler的bean afterpropertiySet 方法中 regist (this)到一个xxxManager中。Manager中持有一个static的Map

实现2

另一种实现方式是用sofa框架的扩展点(spring原生是否有对应机制?不确定,暂时没查到)

原理:一般sofa下,不同bundle的spring上下文是不同的,独立的,不能互相访问。 sofa 扩展点机制提供了一种能力,可以在一个spring上下文中 修改另一个上下文中bean的属性。(当然,在同一个上下文中修改也是可以的)

定义一个贡献点的描述(通常是一个要修改的bean的属性的类型,比如上面的case,就是Map的key value)

  1. @XObject("processor")
  2. public class ProcessorDescriptor {
  3. @XNode("type")
  4. public String type;
  5. @XNode("ref")
  6. public Processor ref;
  7. public String getType() {
  8. return type;
  9. }
  10. public void setType(String type) {
  11. this.type = type;
  12. }
  13. public Processor getRef() {
  14. return ref;
  15. }
  16. public void setRef(Processor ref) {
  17. this.ref = ref;
  18. }
  19. }

定一个一个扩展点

  1. <sofa:extension-point name="taskProcessorExtensionPoint" ref="taskProcessor">
  2. <sofa:object class="com.alipay.antmedia.core.service.upgrade.monitor.processor.ProcessorDescriptor"/>
  3. </sofa:extension-point>
  4. // ref代表是给谁定义扩展点, 就是那个工厂类
  5. // <sofa:object>是定义 贡献点的类型

对定义好的扩展点,进行扩展(这里就好比于,上面只是声明了一个扩展点,这里是对它实例化)

  1. <sofa:extension bean="taskProcessor" point="taskProcessorExtensionPoint">
  2. <sofa:content>
  3. <processor>
  4. <!-- 这里 type ref 对应于 ProcessorDescriptor 中的 @XNode 后面声明的字符串-->
  5. <type>ASSIGN</type>
  6. <ref>ruleAssignerProcessor</ref>
  7. </processor>
  8. </sofa:content>
  9. </sofa:extension>

然后在工厂类中,定义regist 方法

  1. public class TaskProcessor {
  2. private Map<String, Processor> prossors = new HashMap<>();
  3. public void trigger(ProcessContext processContext) {
  4. prossors.get(processContext.getTaskType());
  5. }
  6. /**
  7. * 组件方法,SOFA 框架将会调用这个方法进行扩展点设置,必不可少!
  8. * 只设置了一个贡献点,该方法还比较简单,随着贡献点增多,方法会变复杂。
  9. */
  10. public void registerExtension(Extension extension) {
  11. Object[] contributions = extension.getContributions();
  12. String extensionPoint = extension.getExtensionPoint();
  13. if ("taskProcessorExtensionPoint".equals(extensionPoint)) {
  14. Arrays.stream(contributions).forEach(contribution -> {
  15. ProcessorDescriptor processorDescriptor = (ProcessorDescriptor)contribution;
  16. prossors.put(processorDescriptor.getType(), processorDescriptor.getRef());
  17. });
  18. }
  19. }
  20. public void setProssors(Map<String, Processor> prossors) {
  21. this.prossors = prossors;
  22. }

对比

实现2的方式,通常属性是非static的,如果要获取,需要通过实例化工厂来获取。而实现1直接static的方式获取