最近在将seata和我们的老项目框架进行整合,在整合过程中遇到了一个棘手的问题,我们需要通过自定义的一个配置来决定seata是否开启,通过查看seata的api之后发现当我们将seata的数据源代理和全局事务配置关掉之后,就能关闭全局事务,配置如下:
seata.enable-auto-data-source-proxy=false #关闭数据源代理
seata.service.disable-global-transaction=true #关闭全局事务
但是我们不可能既要修改框架自定义的配置,又去修改spring的配置文件,最终通过查看spring cloud相关文档发现,我们可以通过PropertySourceLocator来实现对默认配置的修改
- 创建一个类,继承MapPropertySource
public class WsdPropertySource extends MapPropertySource { public WsdPropertySource(String name, Map<String, Object> source) { super(name, source); } }
- 创建一个类实现PropertySourceLocator
@Order(0) public class WsdPropertySourceLocator implements PropertySourceLocator { private static final Logger log = LoggerFactory .getLogger(WsdPropertySourceLocator.class); @Override public PropertySource<?> locate(Environment env) { Map<String, Object> source = new HashMap<>(16); // 这里读取框架内自定义的配置 if (!WsdMsConstants.MS_ENABLE) { // 关闭微服务 log.info("关闭微服务:seata"); // 关闭数据源代理 source.put("seata.enable-auto-data-source-proxy", false); // 关闭全局事务 source.put("seata.service.disable-global-transaction", true); } return new WsdPropertySource(WsdMsConstants.WSD_CONFIG_NAME, source); } }
- 构建一个配置类
@Configuration(proxyBeanMethods = false) public class WsdConfigBootstrapConfiguration { @Bean public WsdPropertySourceLocator wsdPropertySourceLocator(){ return new WsdPropertySourceLocator(); } }
- 最重要的一步:在资源文件夹下创建一个目录META-INF里面创建一个文件叫spring.factories
org.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.wisdom.springcloud.WsdConfigBootstrapConfiguration
这一步很重要,如果启动之后发现程序不能运行到WsdPropertySourceLocator中 那可能是因为这里没有配置