通过枚举类型中实现工厂方法,解决Bean注入失败的问题
一、 背景是这样的,我希望构建一个处理工厂类,根据不同的类型执行不一样的处理逻辑。但是根据以往的工厂方法,通过传入一个标识字符串,从工厂类中获取得到相应的处理类,这样就会产生很多的if-else的代码,看起来很不优雅。所以就想通过枚举的方式来处理,可是其中涉及到的一个问题是,处理的方法里面会使用到bean工厂中初始化好的bean,需要注入到枚举类中才可以使用,否则会报空指针异常。
二、整个处理过程是这样的。
-
先定义一个抽象类。
public abstract class BOFlowBusinessHandle<T> { //apporved后执行的逻辑 public abstract void apporveProcess(T v); //reject操作后的执行逻辑 public abstract void rejectProcess(T v); }
-
实现某一个业务的处理逻辑,继承BOFlowBusinessHandle。
public class BOFlowFapiaoReverseHandle extends BOFlowBusinessHandle<String>{ @Autowired private FlowService flowService; @Override public void apporveProcess(String v) { // TODO Auto-generated method stub flowService.apporveProcess(); } @Override public void rejectProcess(String v) { // TODO Auto-generated method stub flowService.rejectProcess(); } }
3.定义一个枚举类型,根据不同的类型,执行不同的业务处理逻辑
public enum BOFlowProcess { FAPIAOREVERSE("fapiaoReverse", new BOFlowFapiaoReverseHandle()); private String code; private BOFlowBusinessHandle<?> boFlowBusinessHandle; private BOFlowProcess(String code) { this.code = code; } private BOFlowProcess(String code, BOFlowBusinessHandle<?> boFlowBusinessHandle) { this.code = code; this.boFlowBusinessHandle = boFlowBusinessHandle; } public static BOFlowBusinessHandle<?> match(String code) { if (StringUtils.isEmpty(code)) { throw new RuntimeException("参数不能为空"); } BOFlowProcess2[] values = BOFlowProcess.values(); BOFlowBusinessHandle<?> baseHandle = null; for (BOFlowProcess businessIndexEnum : values) { if (code.equals(businessIndexEnum.getCode())) { baseHandle = businessIndexEnum.getBoFlowBusinessHandle(); break; } } return baseHandle; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public BOFlowBusinessHandle<?> getBoFlowBusinessHandle() { return boFlowBusinessHandle; } public void setBoFlowBusinessHandle(BOFlowBusinessHandle<?> boFlowBusinessHandle) { this.boFlowBusinessHandle = boFlowBusinessHandle; } }
-
创建测试,发现在BOFlowFapiaoReverseHandle中通过@Autowired注入的flowService为null,即没有注入成功
-
所以经以下改造则正常
public enum BOFlowProcess { FAPIAOREVERSE("fapiaoReverse"){ private ApplicationContext bean; @Override public void setBean(ApplicationContext bean) { this.bean = bean; this.setBoFlowBusinessHandle(bean.getBean(BOFlowFapiaoReverseHandle.class)); logger.info("初始化 fapiaoReverse.bean... "); }}; private String code; private BOFlowBusinessHandle<?> boFlowBusinessHandle; private static Logger logger = Logger.getLogger(BOFlowProcess.class); private BOFlowProcess(String code) { this.code = code; } private BOFlowProcess(String code, BOFlowBusinessHandle<?> boFlowBusinessHandle) { this.code = code; this.boFlowBusinessHandle = boFlowBusinessHandle; } public abstract void setBean(ApplicationContext bean); @Component public static class EnumTypeServiceInjector { @Autowired private ApplicationContext bean; @PostConstruct //这个注解会当所有的Bean都初始化完成之后才执行 public void postConstruct() { for (BOFlowProcess type : EnumSet.allOf(BOFlowProcess.class)) { type.setBean(bean); logger.info("初始化上下文对象"); } } } public static BOFlowBusinessHandle<?> match(String code) { if (StringUtils.isEmpty(code)) { throw new RuntimeException("参数不能为空"); } BOFlowProcess[] values = BOFlowProcess.values(); BOFlowBusinessHandle<?> baseHandle = null; for (BOFlowProcess businessIndexEnum : values) { if (code.equals(businessIndexEnum.getCode())) { baseHandle = businessIndexEnum.getBoFlowBusinessHandle(); break; } } logger.info("获取得到具体的实现类: "+ baseHandle); return baseHandle; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public BOFlowBusinessHandle<?> getBoFlowBusinessHandle() { return boFlowBusinessHandle; } public void setBoFlowBusinessHandle(BOFlowBusinessHandle<?> boFlowBusinessHandle) { this.boFlowBusinessHandle = boFlowBusinessHandle; } }
-
测试
public class TestEnum { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"applicationContext-configuration.xml"}); BOFlowBusinessHandle<FapiaoReverseVO> handle = (BOFlowBusinessHandle<FapiaoReverseVO>) BOFlowProcess.match("fapiaoReverse"); FapiaoReverseVO vo = new FapiaoReverseVO(); vo.setApplyMasterPO(new BOFlow_ApplyMasterPO()); vo.setApprovalLogID("1111"); vo.setHost("https://www.baidu.com"); vo.setNode(1); handle.apporveProcess(vo); System.out.println("执行完成: "+ vo.getReturnMsg().value); } }
这个功能的完成借助参考了以下文章:
https://www.it1352.com/625366.html
-
-