有这样一种场景,对接短信供应商,须要可以根据配置自动切换具体的供应商,java
而Spring@Conditional恰好能够为咱们实现此功能ide
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface Conditional { Class<? extends Condition>[] value(); // 这里须要实现Condition接口 }public class UCloudConditional implements Condition { private Logger log = LoggerFactory.getLogger(UCloudConditional.class); private Properties properties; @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { properties = new Properties(); InputStream is = null; try { is = conditionContext.getResourceLoader().getResource("classpath:xxx.properties").getInputStream(); properties.load(is); return StringUtils.isEmpty(properties.getProperty("sms.used")) ? false : SupplierConstant.UCLOUD.equalsIgnoreCase(properties.getProperty("sms.used")); } catch (Exception e) { log.error("UCloudConditional#matches, load properties fail,e:", e); return false; } finally { if (is != null) { try { is.close(); } catch (IOException e) { log.error("UCloudConditional#matches, load properties fail,e:", e); } } } }public class ClConditional implements Condition { private Properties properties; @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { properties = new Properties(); InputStream is = null; try { is = conditionContext.getResourceLoader().getResource("classpath:xxx.properties").getInputStream(); properties.load(is); return StringUtils.isEmpty(properties.getProperty("sms.used")) ? true : SupplierConstant.CHUANG_LAN.equalsIgnoreCase(properties.getProperty("sms.used")); } catch (Exception e) { log.error("ClConditional#matches, load properties fail,e:", e); return true; // CL做为默认使用的短信服务商 } finally { if (is != null) { try { is.close(); } catch (IOException e) { log.error("ClConditional#matches, load properties fail,e:", e); } } } }@Configuration public class SMSMessageConfiguration { @Bean @Conditional(UCloudConditional.class) public ISendMessageTemplate createUCloudTemplate() { return new UCloudSendMessageTemplate(); } @Bean @Conditional(ClConditional.class) public ISendMessageTemplate createClTemplate() { return new ClSendMessageTemplate(); } }public interface ISendMessageTemplate { BaseResponse sendMessage(String phone, String content); }@Service public class SendMessageAdapter { private ISendMessageTemplate sendMessageTemplate; @Autowired public SendMessageAdapter(ISendMessageTemplate sendMessageTemplate) { this.sendMessageTemplate = sendMessageTemplate; } /** * 短信发送 * * @param phone * @param content * @return */ public BaseResponse sendMessage(String phone, String content) { return this.sendMessageTemplate.sendMessage(phone, content); } }#SpringBoot中的作法this
/**使用配置化的方式参与感更强,但须要更多额外的配置来处理, * 而使用Boot的方式提供一种开箱即用的机制相对来讲更加灵活,只须要注入相关依赖或者 * 取消相关依赖便可 **/ @Primary @Bean @ConditionalOnClass(value = xxx.xx.x.SendUSMSMessageParam.class) public ISendMessageTemplate createUCloudTemplate() { return new UCloudSendMessageTemplate(); } @ConditionalOnMissingClass(value = "xxx.xx.x.SendUSMSMessageParam") @Bean public ISendMessageTemplate createClTemplate() { return new ClSendMessageTemplate(); }