通过枚举类型中实现工厂方法,解决enum注入Bean失败的问题

通过枚举类型中实现工厂方法,解决Bean注入失败的问题

一、 背景是这样的,我希望构建一个处理工厂类,根据不同的类型执行不一样的处理逻辑。但是根据以往的工厂方法,通过传入一个标识字符串,从工厂类中获取得到相应的处理类,这样就会产生很多的if-else的代码,看起来很不优雅。所以就想通过枚举的方式来处理,可是其中涉及到的一个问题是,处理的方法里面会使用到bean工厂中初始化好的bean,需要注入到枚举类中才可以使用,否则会报空指针异常。

二、整个处理过程是这样的。

  1. 先定义一个抽象类。

    public abstract class BOFlowBusinessHandle<T> {
    	//apporved后执行的逻辑
    	public abstract void  apporveProcess(T v);
    	
        //reject操作后的执行逻辑
    	public abstract void rejectProcess(T v);
    
    }
    
  2. 实现某一个业务的处理逻辑,继承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;
    	}
    
    }
    
    
    1. 创建测试,发现在BOFlowFapiaoReverseHandle中通过@Autowired注入的flowService为null,即没有注入成功

    2. 所以经以下改造则正常

      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;
      	}
      
      }
      
      
      1. 测试

        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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值