Closed fighter2011 closed 3 years ago
可以跟进一下看看源码行吗
可以跟进一下看看源码行吗
我看了源码了的,使用springboot-steata-starter没有registry.conf文件,解析得到ConfigurationFactory默认是FileConfiguration,SpringBootConfigurationProvider在获取属性的时候StarterConstants对应的PROPERTY_MAP没有Custom对应的properties然后解析出来就是null
这个要自己定义一个Provider 放在/META-INF/seata下 这是我的配置,使用自定义配置类型,自定义从ApplicationContext.Environment里去取参数: 这样我们的配置就可以放在配置文件里了,也可以天然支持配置中心
seata.config.type=Custom
seata.config.custom.name=CqlivingSeataConfig
org.cqliving.framework.cloud.seata.CqlivingSeataConfigurationProvider
3.META-INF/seata/io.seata.config.ExtConfigurationProvider
org.cqliving.framework.cloud.seata.CqlivingSeataConfigurationProvider
4.CqlivingSeataConfigurationProvider
package org.cqliving.framework.cloud.seata;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.context.ApplicationContext;
import io.seata.common.loader.LoadLevel;
import io.seata.config.Configuration;
import io.seata.config.ConfigurationProvider;
import io.seata.config.ExtConfigurationProvider;
import io.seata.spring.boot.autoconfigure.util.SpringUtils;
/********************************************************/
@LoadLevel(name = "CqlivingSeataConfig", order = 1)
public class CqlivingSeataConfigurationProvider implements ExtConfigurationProvider, ConfigurationProvider {
private static final String GET ="get";
private static final String PREFIX ="seata.";
@Override
public Configuration provide(Configuration originalConfiguration) {
ApplicationContext applicationContext = SpringUtils.getApplicationContext();
return (Configuration)Enhancer.create(originalConfiguration.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)
throws Throwable {
if (method.getName().startsWith(GET) && args.length > 0) {
Object result = null;
String rawDataId = (String)args[0];
if (args.length == 1) {
result = applicationContext.getEnvironment().getProperty(PREFIX.concat(rawDataId));
}
if (null != result) {
return result;
}
}
return method.invoke(originalConfiguration, args);
}
});
}
@Override
public Configuration provide() {
return CqlivingSeataConfiguration.getInstance();
}
}
package org.cqliving.framework.cloud.seata;
import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.util.ObjectUtils; import io.seata.config.AbstractConfiguration; import io.seata.config.ConfigurationChangeListener; import io.seata.spring.boot.autoconfigure.util.SpringUtils;
public class CqlivingSeataConfiguration extends AbstractConfiguration{
private static final Logger logger = LoggerFactory.getLogger(CqlivingSeataConfiguration.class);
private static final String CONFIG_TYPE = "CqlivingSeataConfig";
private static final String PREFIX = "seata.";
private static volatile CqlivingSeataConfiguration instance;
private static final ConcurrentMap<String, Set<ConfigurationChangeListener>> LISTENER_SERVICE_MAP = new ConcurrentHashMap<>();
public static CqlivingSeataConfiguration getInstance() {
if (null == instance) {
synchronized (CqlivingSeataConfiguration.class) {
if (null == instance) {
instance = new CqlivingSeataConfiguration();
}
}
}
return instance;
}
private CqlivingSeataConfiguration() {}
private static final char LINE = '-';
@Override
public String getConfig(String dataId, String defaultValue, long timeoutMills) {
dataId = dataId.startsWith(PREFIX)?dataId: PREFIX.concat(formatCamel(dataId, LINE));
String value;
// 从系统变量获取
if ((value = getConfigFromSysPro(dataId)) != null) {
return value;
}
// 从配置文件获取
ApplicationContext applicationContext = SpringUtils.getApplicationContext();
if (null == applicationContext) {
return defaultValue;
}
value = applicationContext.getEnvironment().getProperty(dataId);
if(null == value) {
logger.error("properties null [{}] ", dataId);
return defaultValue;
}
return value;
}
private String formatCamel(String param, char sign) {
if (ObjectUtils.isEmpty(param)) {
return StringUtils.EMPTY;
}
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (Character.isUpperCase(c)) {
sb.append(sign);
sb.append(Character.toLowerCase(c));
} else {
sb.append(c);
}
}
return sb.toString();
}
@Override
public boolean putConfig(String dataId, String content, long timeoutMills) {
throw new UnsupportedOperationException();
}
@Override
public boolean putConfigIfAbsent(String dataId, String content, long timeoutMills) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeConfig(String dataId, long timeoutMills) {
throw new UnsupportedOperationException();
}
@Override
public void addConfigListener(String dataId, ConfigurationChangeListener listener) {
if (null == dataId || null == listener) {
return;
}
LISTENER_SERVICE_MAP.putIfAbsent(dataId, ConcurrentHashMap.newKeySet());
LISTENER_SERVICE_MAP.get(dataId).add(listener);
}
@Override
public void removeConfigListener(String dataId, ConfigurationChangeListener listener) {
if (!LISTENER_SERVICE_MAP.containsKey(dataId) || listener == null) {
return;
}
LISTENER_SERVICE_MAP.get(dataId).remove(listener);
}
@Override
public Set<ConfigurationChangeListener> getConfigListeners(String dataId) {
return LISTENER_SERVICE_MAP.get(dataId);
}
@Override
public String getTypeName() {
return CONFIG_TYPE;
}
}
6.SeataAutoConfiguration.java
package org.cqliving.framework.cloud.seata;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import io.seata.config.springcloud.EnableSeataSpringConfig; import io.seata.spring.annotation.datasource.EnableAutoDataSourceProxy;
/****/
@Configuration @PropertySource("classpath:seata.properties") @EnableAutoDataSourceProxy @EnableSeataSpringConfig @EnableConfigurationProperties({CustomProperties.class}) public class SeataAutoConfiguration {
}
7. seata.properties
seata.config.type=Custom seata.config.custom.name=CqlivingSeataConfig
spring.cloud.alibaba.seata.tx-service-group=cqliving-seata-group
seata.client.rm.async-commit-buffer-limit=10000 seata.client.rm-report-retry-count=5 seata.client.rm.table-meta-check-enable=false seata.client.rm-report-success-enable=false seata.client.rm.sql-parser-type=druid seata.client.tm-commit-retry-count=5 seata.client.tm-rollback-retry-count=5
seata.client.rm.lock.lock-retry-interval=10 seata.client.rm.lock.lock-retry-times=30 seata.client.rm.lock.lock-retry-policy-branch-rollback-on-conflict=true
seata.client.log.exception-rate=100
seata.service.vgroupMapping.cqliving-seata-group=seata-server seata.service.enable-degrade=false seata.service.disable-global-transaction=false
seata.transport.shutdown.wait=3
seata.client.support.spring.datasource-autoproxy=true
seata.transport.thread-factory.boss-thread-prefix=NettyBoss seata.transport.thread-factory.worker-thread-prefix=NettyServerNIOWorker seata.transport.thread-factory.server-executor-thread-prefix=NettyServerBizHandler seata.transport.thread-factory.share-boss-worker=false seata.transport.thread-factory.client-selector-thread-prefix=NettyClientSelector seata.transport.thread-factory.client-selector-thread-size=1 seata.transport.thread-factory.client-worker-thread-prefix=NettyClientWorkerThread seata.transport.thread-factory.boss-thread-size=1 seata.transport.thread-factory.worker-thread-size=8
seata.transport.type=TCP seata.transport.server=NIO seata.transport.heartbeat=true seata.transport.serialization=seata seata.transport.compressor=none seata.transport.enable-client-batch-send-request=false
seata.client.undo.undo-data-validation=true seata.client.undo.undo-log-serialization=jackson seata.client.undo.undo-log-table=undo_log
seata.registry.type=eureka seata.registry.eureka.application=${spring.application.name} seata.registry.eureka.serviceUrl=${eureka.client.service-url.defaultZone} seata.registry.eureka.weight=1
@fighter2011 Welcome to contribute to the community by submitting a pr fix for this problem.
Ⅰ. Issue Description
使用springboot-seata-starter自定义配置时解析配置失败
Ⅱ. Describe what happened
使用cutom的形式来实现,但是yaml配置seate.config.type.custom seata.config.custom.name,CustomConfigurationProvider获取配置的时候,解析不到seata.config.custom.name配置的值 If there is an exception, please attach the exception trace:
Ⅲ. Describe what you expected to happen
Ⅳ. How to reproduce it (as minimally and precisely as possible)
Ⅴ. Anything else we need to know?
Ⅵ. Environment: