欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

借助@Conditional实现自定义初始化Spring Bean

程序员文章站 2022-05-23 18:13:24
...

本项目使用传统的Spring MVC框架进行搭建,未使用Spring Boot,而需要实现根据用户配置自动选择TCP、UDP、串口等不同协议进行数据获取,还有用户若在内网,实现短信服务动态关闭(wsimport 方式实现的,用户配置修改后Spring不加载相应的短信服务)。若使用Spring Boot,Spring Boot提供了一系列根据条件初始化Spring Bean的注解,非常方便的进行此等操作,在传统Spring MVC项目中,可自己借助@Conditional实现以上操作。

  • 协议动态选择

    • 首先定义不同协议的注解

      /**
      * @类名 ServerType
      * @描述 不同协议初始化不同服务器(0:TCP,1:UDP,2:串口)
      * @作者 zhuxl
      * @创建时间 2017-3-28下午04:50:55
      */
      public class ServerType {
      /**
       * @类名 TCP
       * @描述 TCP
       * @作者 zhuxl
       * @创建时间 2017-3-28下午04:55:38
       */
      public @interface TCP {
      
      }
      
      /**
       * @类名 UDP
       * @描述 UDP
       * @作者 zhuxl
       * @创建时间 2017-3-28下午04:55:43
       */
      public @interface UDP {
      
      }
      
      /**
       * @类名 Serial
       * @描述 串口
       * @作者 zhuxl
       * @创建时间 2017-3-28下午04:55:48
       */
      public @interface Serial {
      
      }
      }
    • 根据配置文件中不同的配置,实现对不同协议的处理

    /**
     * @类名 ServerCondition
     * @描述 服务器条件初始化(根据配置自动初始化不同的服务器)
     * @作者 zhuxl
     * @创建时间 2017-4-1下午01:30:48
     */
    public class ServerCondition implements Condition{
    
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            int type=PropUtil.getInt(Constant.SETTING_PATH, "transport.type", 0);
            switch(type){
                case 1:{//UDP
                    return metadata.isAnnotated(UDP.class.getName());
                }
                case 2:{//串口
                    return metadata.isAnnotated(Serial.class.getName());
                }
                default:{//TCP
                    return metadata.isAnnotated(TCP.class.getName());
                }
            }       
        }
    }
    
    • 对于不同的协议类型,初始化不同的Bean
      //串口处理
      @Component("minaServer")
      @Conditional(value=ServerCondition.class)
      @Serial
      public class SerialServer implements Server {
      }
      // TCP处理
      @Component("minaServer")
      @Conditional(value=ServerCondition.class)
      @TCP
      public class TCPServer implements Server {
      }
  • 短信服务动态关闭:根据配置,能够实现短信服务动态加载(短信服务时wsimport加载的)

    • 短信服务条件初始化
      /**
      * @类名 SmsCondition
      * @描述 短信服务条件初始化
      * @作者 zhuxl
      * @创建时间 2017-6-12下午04:58:58
      */
      public class SmsCondition implements Condition{
          @Override
          public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
              int flag=PropUtil.getInt(Constant.SETTING_PATH, "sms.use", 0);
              return flag==1?true:false;
          }
      }
  • 短信服务Bean动态加载
/**
 * @类名 SmsConfig
 * @描述 短信条件初始化
 * @作者 zhuxl
 * @创建时间 2017-6-12下午05:13:14
 */
@Configuration
@Conditional(SmsCondition.class)
public class SmsConfig {
    @Bean 
    public SmSWebService smSWebService(){
        return new SmSWebService();
    }
    @Bean
    public SmSWebServiceSoap smSWebServiceSoap(SmSWebService smSWebService){
        return smSWebService.getSmSWebServiceSoap();
    }
} 
  • 在需要短信的地方使用以下代码加入短信服务,但使用前需要判断短信服务是否为空,为空则为加载。
    @Autowired(required=false) @Qualifier("smSWebServiceSoap")
    private SmSWebServiceSoap smSWebServiceSoap;

    public String sendSms(Sms sms) {
        if(smSWebServiceSoap==null){
            return "短信功能不可用,请确定短信服务可用";
        }
        if(sms==null){
            return "短信参数错误";
        }
        try{
            WsSendResponse response=smSWebServiceSoap.sendSms(smsAccount.getUserId(), smsAccount.getAccount(), smsAccount.getPassword(), sms.getMobile(), sms.getContent(), sms.getSendTime(), sms.getExtno());
            logger.info("短信发送:"+response.getMessage()+","+response.getReturnStatus());
            return response.getMessage();
        }catch(Exception ex){
            ex.printStackTrace();
            return "短信发送失败";
        }
    }
相关标签: spring