diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6da51403d..fb80840ca 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,4 +15,5 @@
 - [fix: fix lossless deregister failed when no healthcheck configured](https://github.com/Tencent/spring-cloud-tencent/pull/1385)
 - [feat:add zero protection.](https://github.com/Tencent/spring-cloud-tencent/pull/1386)
 - [fix:fix no registry when lossless is disabled.](https://github.com/Tencent/spring-cloud-tencent/pull/1388)
-- [fix:fix the ratelimit bug](https://github.com/Tencent/spring-cloud-tencent/pull/1389)
\ No newline at end of file
+- [fix:fix the ratelimit bug](https://github.com/Tencent/spring-cloud-tencent/pull/1389)
+- [feat:add Tencent Cloud TSF support.](https://github.com/Tencent/spring-cloud-tencent/pull/1391)
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigCustomExtensionLayer.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigCustomExtensionLayer.java
index 19d873857..592368c68 100644
--- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigCustomExtensionLayer.java
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigCustomExtensionLayer.java
@@ -29,6 +29,8 @@ import org.springframework.core.env.Environment;
  * @author juanyinyang
  */
 public interface PolarisConfigCustomExtensionLayer {
+	boolean isEnabled();
+
 	void initRegisterConfig(PolarisConfigPropertyAutoRefresher polarisConfigPropertyAutoRefresher);
 
 	void initConfigFiles(Environment environment, CompositePropertySource compositePropertySource, ConfigFileService configFileService);
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisServiceLoaderUtil.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisServiceLoaderUtil.java
index 343a5b319..bf61aac4d 100644
--- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisServiceLoaderUtil.java
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisServiceLoaderUtil.java
@@ -30,20 +30,25 @@ import org.slf4j.LoggerFactory;
 public final class PolarisServiceLoaderUtil {
 
 	private static final Logger LOGGER = LoggerFactory.getLogger(PolarisServiceLoaderUtil.class);
-	private PolarisServiceLoaderUtil() {
-	}
 	// this class provides customized logic for some customers to configure special business group files
 	private static PolarisConfigCustomExtensionLayer polarisConfigCustomExtensionLayer;
+
 	static {
 		ServiceLoader<PolarisConfigCustomExtensionLayer> polarisConfigCustomExtensionLayerLoader = ServiceLoader.load(PolarisConfigCustomExtensionLayer.class);
 		Iterator<PolarisConfigCustomExtensionLayer> polarisConfigCustomExtensionLayerIterator = polarisConfigCustomExtensionLayerLoader.iterator();
 		// Generally, there is only one implementation class. If there are multiple, the last one is loaded
 		while (polarisConfigCustomExtensionLayerIterator.hasNext()) {
-			polarisConfigCustomExtensionLayer = polarisConfigCustomExtensionLayerIterator.next();
-			LOGGER.info("[SCT Config] PolarisConfigFileLocator init polarisConfigCustomExtensionLayer:{}", polarisConfigCustomExtensionLayer);
+			PolarisConfigCustomExtensionLayer temp = polarisConfigCustomExtensionLayerIterator.next();
+			if (temp.isEnabled()) {
+				polarisConfigCustomExtensionLayer = temp;
+				LOGGER.info("[SCT Config] PolarisConfigFileLocator init polarisConfigCustomExtensionLayer:{}", polarisConfigCustomExtensionLayer);
+			}
 		}
 	}
 
+	private PolarisServiceLoaderUtil() {
+	}
+
 	public static PolarisConfigCustomExtensionLayer getPolarisConfigCustomExtensionLayer() {
 		return polarisConfigCustomExtensionLayer;
 	}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/PolarisAdaptorTsfConfigAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/PolarisAdaptorTsfConfigAutoConfiguration.java
new file mode 100644
index 000000000..7c4f8ac9a
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/PolarisAdaptorTsfConfigAutoConfiguration.java
@@ -0,0 +1,77 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.config.tsf;
+
+import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
+import com.tencent.cloud.polaris.config.ConditionalOnPolarisConfigEnabled;
+import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
+import com.tencent.cloud.polaris.config.tsf.controller.PolarisAdaptorTsfConfigController;
+import com.tencent.cloud.polaris.context.tsf.config.TsfCoreProperties;
+import com.tencent.tsf.consul.config.watch.TsfConsulConfigRefreshEventListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author juanyinyang
+ * @Date Jul 23, 2023 3:52:48 PM
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnTsfEnabled
+@ConditionalOnPolarisConfigEnabled
+public class PolarisAdaptorTsfConfigAutoConfiguration {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(PolarisAdaptorTsfConfigAutoConfiguration.class);
+
+	{
+		System.setProperty("spring.cloud.polaris.config.refresh-type", "refresh_context");
+		LOGGER.info(
+				"[SCTT Config] PolarisAdaptorTsfConfigAutoConfiguration init set spring.cloud.polaris.config.refresh-type to refresh_context");
+	}
+
+	@Bean
+	@ConditionalOnMissingBean
+	@ConditionalOnProperty(name = "spring.cloud.consul.config.watch.enabled", matchIfMissing = true)
+	public TsfConsulConfigRefreshEventListener polarisAdaptorTsfConsulRefreshEventListener() {
+		return new TsfConsulConfigRefreshEventListener();
+	}
+
+	/**
+	 * 初始化本类的条件:
+	 * 1、关闭Spring Cloud Consul Config配置开关(如果开启Consul Config配置开关,那么初始化的是tsf自身的类ConfigController)
+	 * 2、开启北极星配置(本类通过注解@ConditionalOnPolarisConfigEnabled开启)
+	 * 3、tsf.config.instance.released-config.lookup.enabled的开关是打开的(默认不配置就是打开的).
+	 */
+	@Bean
+	@ConditionalOnMissingBean
+	@ConditionalOnExpression("${spring.cloud.consul.config.enabled:true} == false and ${tsf.config.instance.released-config.lookup.enabled:true} == true")
+	public PolarisAdaptorTsfConfigController polarisAdaptorTsfConfigController() {
+		return new PolarisAdaptorTsfConfigController();
+	}
+
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfConfigurationModifier tsfConfigModifier(TsfCoreProperties tsfCoreProperties, PolarisConfigProperties polarisConfigProperties) {
+		return new TsfConfigurationModifier(tsfCoreProperties, polarisConfigProperties);
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/PolarisAdaptorTsfConfigBootstrapConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/PolarisAdaptorTsfConfigBootstrapConfiguration.java
new file mode 100644
index 000000000..3c927ee63
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/PolarisAdaptorTsfConfigBootstrapConfiguration.java
@@ -0,0 +1,39 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.config.tsf;
+
+import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
+import com.tencent.cloud.polaris.config.ConditionalOnPolarisConfigEnabled;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * @author juanyinyang
+ * @Date Jul 23, 2023 3:52:48 PM
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnProperty("spring.cloud.polaris.enabled")
+@ConditionalOnTsfEnabled
+@ConditionalOnPolarisConfigEnabled
+@Import(PolarisAdaptorTsfConfigAutoConfiguration.class)
+public class PolarisAdaptorTsfConfigBootstrapConfiguration {
+
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/TsfConfigurationModifier.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/TsfConfigurationModifier.java
new file mode 100644
index 000000000..9799e872b
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/TsfConfigurationModifier.java
@@ -0,0 +1,54 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.config.tsf;
+
+import com.tencent.cloud.common.constant.OrderConstant;
+import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
+import com.tencent.cloud.polaris.context.PolarisConfigModifier;
+import com.tencent.cloud.polaris.context.tsf.config.TsfCoreProperties;
+import com.tencent.polaris.factory.config.ConfigurationImpl;
+
+/**
+ * TSF config modifier.
+ *
+ * @author Haotian Zhang
+ */
+public class TsfConfigurationModifier implements PolarisConfigModifier {
+
+
+	private final TsfCoreProperties tsfCoreProperties;
+
+	private final PolarisConfigProperties polarisConfigProperties;
+
+	public TsfConfigurationModifier(TsfCoreProperties tsfCoreProperties, PolarisConfigProperties polarisConfigProperties) {
+		this.tsfCoreProperties = tsfCoreProperties;
+		this.polarisConfigProperties = polarisConfigProperties;
+	}
+
+	@Override
+	public void modify(ConfigurationImpl configuration) {
+		if (polarisConfigProperties != null && tsfCoreProperties != null) {
+			polarisConfigProperties.setEnabled(tsfCoreProperties.isTsePolarisEnable());
+		}
+	}
+
+	@Override
+	public int getOrder() {
+		return OrderConstant.Modifier.CONFIG_ORDER - 1;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/adaptor/PolarisAdaptorTsfConfigExtensionLayer.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/adaptor/PolarisAdaptorTsfConfigExtensionLayer.java
new file mode 100755
index 000000000..94d32cff0
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/adaptor/PolarisAdaptorTsfConfigExtensionLayer.java
@@ -0,0 +1,291 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.config.tsf.adaptor;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.google.common.collect.Sets;
+import com.tencent.cloud.polaris.config.adapter.PolarisConfigCustomExtensionLayer;
+import com.tencent.cloud.polaris.config.adapter.PolarisConfigPropertyAutoRefresher;
+import com.tencent.cloud.polaris.config.adapter.PolarisPropertySource;
+import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager;
+import com.tencent.cloud.polaris.config.enums.ConfigFileFormat;
+import com.tencent.cloud.polaris.config.tsf.cache.PolarisPropertyCache;
+import com.tencent.cloud.polaris.config.tsf.encrypt.EncryptConfig;
+import com.tencent.polaris.configuration.api.core.ConfigFileGroup;
+import com.tencent.polaris.configuration.api.core.ConfigFileGroupChangeListener;
+import com.tencent.polaris.configuration.api.core.ConfigFileGroupChangedEvent;
+import com.tencent.polaris.configuration.api.core.ConfigFileMetadata;
+import com.tencent.polaris.configuration.api.core.ConfigFileService;
+import com.tencent.polaris.configuration.api.core.ConfigKVFile;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.core.env.CompositePropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * @author juanyinyang
+ */
+public class PolarisAdaptorTsfConfigExtensionLayer implements PolarisConfigCustomExtensionLayer {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(PolarisAdaptorTsfConfigExtensionLayer.class);
+	/**
+	 * 应用配置.
+	 */
+	private static final String APP_CONFIG = "appconfig";
+	/**
+	 * 全局配置.
+	 */
+	private static final String PUB_CONFIG = "pubconfig";
+	/**
+	 * TSF应用ID.
+	 */
+	private static final String TSF_APPLICATION_ID = "tsf_application_id";
+	/**
+	 * TSF部署组ID.
+	 */
+	private static final String TSF_GROUP_ID = "tsf_group_id";
+	/**
+	 * TSF命名空间ID.
+	 */
+	private static final String TSF_NAMESPACE_ID = "tsf_namespace_id";
+	/**
+	 * TSF命名空间ID.
+	 */
+	private static final String POLARIS_ADAPTOR_TSF_CONFIG_FORMAT = "spring.cloud.polaris.config.format";
+
+	// 最近一次的全量PolarisPropertySource集合(PolarisPropertySource按 namespace + fileGroup + fileName 确保唯一)
+	private static final Set<String> registedPolarisPropertySets = Sets.newConcurrentHashSet();
+	// 命名空间分组(namespace + fileGroup)的去重Set集合,如果这个分组已添加了ConfigFileGroupListener
+	private static final Set<String> registedConfigFileGroupListenerSets = Sets.newConcurrentHashSet();
+
+	private PolarisConfigPropertyAutoRefresher polarisConfigPropertyAutoRefresher;
+
+	@Override
+	public boolean isEnabled() {
+		// tse_polaris_enable
+		String tsePolarisEnable = System.getenv("tse_polaris_enable");
+		if (StringUtils.isBlank(tsePolarisEnable)) {
+			tsePolarisEnable = System.getProperty("tse_polaris_enable", "false");
+		}
+		return StringUtils.equals(tsePolarisEnable, "true");
+	}
+
+	/**
+	 * @see PolarisConfigCustomExtensionLayer#initConfigFiles(CompositePropertySource,
+	 *        PolarisPropertySourceManager,
+	 *        ConfigFileService)
+	 */
+	@Override
+	public void initConfigFiles(Environment environment, CompositePropertySource compositePropertySource,
+			ConfigFileService configFileService) {
+		String tsfApplicationId = environment.getProperty(TSF_APPLICATION_ID);
+		String tsfGroupId = environment.getProperty(TSF_GROUP_ID);
+		String tsfNamespaceId = environment.getProperty(TSF_NAMESPACE_ID);
+		String polarisAdaptorTsfConfigFormat = environment.getProperty(POLARIS_ADAPTOR_TSF_CONFIG_FORMAT);
+		LOGGER.info(
+				"[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer initConfigFiles start, tsfNamespaceId:{}, tsfApplicationId:{}, tsfGroupId:{}",
+				tsfNamespaceId, tsfApplicationId, tsfGroupId);
+		loadAllPolarisConfigFile(compositePropertySource, configFileService,
+				tsfNamespaceId, tsfApplicationId, tsfGroupId, polarisAdaptorTsfConfigFormat);
+		LOGGER.info("[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer initConfigFiles end");
+	}
+
+	private void loadAllPolarisConfigFile(CompositePropertySource compositePropertySource,
+			ConfigFileService configFileService, String tsfNamespaceId, String tsfApplicationId, String tsfGroupId,
+			String polarisAdaptorTsfConfigFormat) {
+		boolean isInitTsfEnv = StringUtils.isNotBlank(tsfNamespaceId) && StringUtils.isNotBlank(tsfApplicationId)
+				&& StringUtils.isNotBlank(tsfGroupId);
+		if (isInitTsfEnv) {
+			String appConfigGroup = APP_CONFIG + "." + tsfApplicationId + "." + tsfGroupId;
+			loadPolarisConfigFile(tsfNamespaceId, tsfApplicationId, tsfGroupId, polarisAdaptorTsfConfigFormat,
+					compositePropertySource, configFileService, appConfigGroup);
+		}
+
+		String pubConfigGroup = PUB_CONFIG;
+		loadPolarisConfigFile(tsfNamespaceId, tsfApplicationId, tsfGroupId, polarisAdaptorTsfConfigFormat,
+				compositePropertySource, configFileService, pubConfigGroup);
+	}
+
+	private PolarisPropertySource loadPolarisPropertySource(String namespace, String group, String fileName,
+			String polarisAdaptorTsfConfigFormat, ConfigFileService configFileService) {
+		ConfigKVFile configKVFile;
+		if (StringUtils.isNotBlank(polarisAdaptorTsfConfigFormat)) {
+			switch (polarisAdaptorTsfConfigFormat) {
+			case "properties":
+				configKVFile = configFileService.getConfigPropertiesFile(namespace, group, fileName);
+			case "yaml":
+			default:
+				configKVFile = configFileService.getConfigYamlFile(namespace, group, fileName);
+			}
+		}
+		// unknown extension is resolved as yaml file
+		else if (ConfigFileFormat.isYamlFile(fileName) || ConfigFileFormat.isUnknownFile(fileName)) {
+			configKVFile = configFileService.getConfigYamlFile(namespace, group, fileName);
+		}
+		else if (ConfigFileFormat.isPropertyFile(fileName)) {
+			configKVFile = configFileService.getConfigPropertiesFile(namespace, group, fileName);
+		}
+		else {
+			LOGGER.warn("[SCTT Config] Unsupported config file. namespace = {}, group = {}, fileName = {}", namespace,
+					group, fileName);
+
+			throw new IllegalStateException("Only configuration files in the format of properties / yaml / yaml"
+					+ " can be injected into the spring context");
+		}
+
+		Map<String, Object> map = new ConcurrentHashMap<>();
+		for (String key : configKVFile.getPropertyNames()) {
+			String value = configKVFile.getProperty(key, null);
+			if (EncryptConfig.needDecrypt(value)) {
+				LOGGER.debug("[SCTT Config] Need Decrypt {}: {}", key, value);
+				value = EncryptConfig.getProvider()
+						.decrypt(EncryptConfig.realContent(value), EncryptConfig.getPassword());
+			}
+			map.put(key, value);
+		}
+
+		return new PolarisPropertySource(namespace, group, fileName, configKVFile, map);
+	}
+
+	private void loadPolarisConfigFile(String namespace, String tsfApplicationId, String tsfGroupId,
+			String polarisAdaptorTsfConfigFormat, CompositePropertySource compositePropertySource,
+			ConfigFileService configFileService, String configGroup) {
+		LOGGER.debug(
+				"[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer loadPolarisConfigFile start, namespace:{}, group:{}",
+				namespace, configGroup);
+		ConfigFileGroup configFileGroup = configFileService.getConfigFileGroup(namespace, configGroup);
+		if (configFileGroup == null) {
+			throw new IllegalStateException(
+					"[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer configFileGroup is null");
+		}
+		List<ConfigFileMetadata> configFileMetadataList = configFileGroup.getConfigFileMetadataList();
+		if (!CollectionUtils.isEmpty(configFileMetadataList)) {
+			LOGGER.info("[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer getConfigFileMetadataList:{}",
+					configFileMetadataList);
+			for (ConfigFileMetadata configFile : configFileMetadataList) {
+				PolarisPropertySource polarisPropertySource = loadPolarisPropertySource(configFile.getNamespace(),
+						configFile.getFileGroup(), configFile.getFileName(), polarisAdaptorTsfConfigFormat,
+						configFileService);
+
+				compositePropertySource.addPropertySource(polarisPropertySource);
+
+				PolarisPropertySourceManager.addPropertySource(polarisPropertySource);
+
+				LOGGER.info(
+						"[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer Load and inject polaris config file from config group:{}. file = {}",
+						configGroup, configFile);
+			}
+		}
+
+		String namespaceConfigGroup = namespace + "-" + configGroup;
+		// 用ConcurrentHashSet保证不重复添加ConfigFileGroupChangeListener
+		if (registedConfigFileGroupListenerSets.add(namespaceConfigGroup)) {
+			LOGGER.info(
+					"[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer configFileGroup addChangeListener namespaceConfigGroup:{}",
+					namespaceConfigGroup);
+			configFileGroup.addChangeListener(new ConfigFileGroupChangeListener() {
+
+				@Override
+				public void onChange(ConfigFileGroupChangedEvent event) {
+					try {
+						LOGGER.info("[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer receive onChange event:{}",
+								event);
+						List<ConfigFileMetadata> configFileMetadataList = event.getConfigFileMetadataList();
+						if (CollectionUtils.isEmpty(configFileMetadataList)) {
+							LOGGER.info(
+									"[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer receive configFileMetadataList is empty");
+							return;
+						}
+						boolean needRefreshAll = false;
+						for (ConfigFileMetadata configFile : configFileMetadataList) {
+							PolarisPropertySource polarisPropertySource = loadPolarisPropertySource(
+									configFile.getNamespace(), configFile.getFileGroup(), configFile.getFileName(),
+									polarisAdaptorTsfConfigFormat, configFileService);
+							LOGGER.info(
+									"[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer Load and inject polaris config file from onChange event config group:{}. file = {}",
+									configGroup, configFile);
+							// 用ConcurrentHashSet保证不重复注册PolarisConfigPublishChangeListener
+							if (executeRegisterPublishChangeListener(polarisPropertySource)) {
+								polarisConfigPropertyAutoRefresher.registerPolarisConfigPublishChangeListener(
+										polarisPropertySource);
+								needRefreshAll = true;
+							}
+						}
+						if (needRefreshAll) {
+							LOGGER.info("[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer start refresh All Config");
+							polarisConfigPropertyAutoRefresher.refreshConfigurationProperties(null);
+						}
+					}
+					catch (Exception e) {
+						LOGGER.info("[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer receive onChange exception:",
+								e);
+					}
+				}
+			});
+		}
+
+		LOGGER.info(
+				"[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer loadPolarisConfigFile end, namespace:{}, group:{}",
+				namespace, configGroup);
+	}
+
+	/**
+	 * @see PolarisConfigCustomExtensionLayer#executeAfterLocateConfigReturning(CompositePropertySource)
+	 */
+	@Override
+	public void executeAfterLocateConfigReturning(CompositePropertySource compositePropertySource) {
+		PolarisPropertyCache.getInstance().clear();
+		PolarisPropertyCache.getInstance().getCache()
+				.addAll(new HashSet<>(Arrays.asList(compositePropertySource.getPropertyNames())));
+		LOGGER.info("[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer executeAfterLocateConfigReturning finished");
+	}
+
+	/**
+	 * @see PolarisConfigCustomExtensionLayer#initRegisterConfig(PolarisConfigPropertyAutoRefresher)
+	 */
+	@Override
+	public void initRegisterConfig(PolarisConfigPropertyAutoRefresher polarisConfigPropertyAutoRefresher) {
+		LOGGER.info(
+				"[SCTT Config] PolarisAdaptorTsfConfigExtensionLayer initRegisterConfig polarisConfigPropertyAutoRefresher:{}",
+				polarisConfigPropertyAutoRefresher.getClass());
+		this.polarisConfigPropertyAutoRefresher = polarisConfigPropertyAutoRefresher;
+	}
+
+	/**
+	 * @see PolarisConfigCustomExtensionLayer#executeRegisterPublishChangeListener(PolarisPropertySource)
+	 */
+	@Override
+	public boolean executeRegisterPublishChangeListener(PolarisPropertySource polarisPropertySource) {
+		boolean isRegisterSuccess = registedPolarisPropertySets.add(polarisPropertySource.getPropertySourceName());
+		if (isRegisterSuccess) {
+			// 已防止重复注册,仅打印注册成功的即可
+			LOGGER.info("[SCTT Config] start to register configFile polarisConfigPublishChangeListener:{}",
+					polarisPropertySource);
+		}
+		return isRegisterSuccess;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/cache/PolarisPropertyCache.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/cache/PolarisPropertyCache.java
new file mode 100644
index 000000000..4e80d0386
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/cache/PolarisPropertyCache.java
@@ -0,0 +1,48 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package com.tencent.cloud.polaris.config.tsf.cache;
+
+import java.util.HashSet;
+import java.util.Set;
+
+
+/**
+ * @author juanyinyang
+ * @Date 2023年8月8日 下午4:56:18
+ */
+public final class PolarisPropertyCache {
+
+	private static final PolarisPropertyCache instance = new PolarisPropertyCache();
+
+	private final Set<String> cache = new HashSet<>();
+
+	private PolarisPropertyCache() {
+
+	}
+
+	public static PolarisPropertyCache getInstance() {
+		return instance;
+	}
+
+	public Set<String> getCache() {
+		return cache;
+	}
+
+	public void clear() {
+		cache.clear();
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/controller/PolarisAdaptorTsfConfigController.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/controller/PolarisAdaptorTsfConfigController.java
new file mode 100755
index 000000000..b8719b0fb
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/controller/PolarisAdaptorTsfConfigController.java
@@ -0,0 +1,60 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.config.tsf.controller;
+
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import com.tencent.cloud.polaris.config.tsf.cache.PolarisPropertyCache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author juanyinyang
+ * @Date 2023年8月2日 下午5:08:29
+ */
+@RestController
+public class PolarisAdaptorTsfConfigController {
+
+	private static final Logger LOG = LoggerFactory.getLogger(PolarisAdaptorTsfConfigController.class);
+
+	@Autowired
+	Environment environment;
+
+	public PolarisAdaptorTsfConfigController() {
+		LOG.info("[SCTT Config] init PolarisAdaptorTsfConfigController");
+	}
+
+	/**
+	 * 兼容目前TSF控制台的用法,提供北极星查询当前SDK配置接口.
+	 */
+	@RequestMapping("/tsf/innerApi/config/findAllConfig")
+	public Map<String, Object> findAllConfig() {
+		Set<String> keys = PolarisPropertyCache.getInstance().getCache();
+		return keys.stream()
+				.collect(HashMap::new, (map, key) -> map.put(key, environment.getProperty(key)), HashMap::putAll);
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/ConfigEncryptAESProvider.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/ConfigEncryptAESProvider.java
new file mode 100644
index 000000000..51f99e8bf
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/ConfigEncryptAESProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.config.tsf.encrypt;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ConfigEncryptAESProvider extends ConfigEncryptProvider {
+
+	private static final Logger log = LoggerFactory.getLogger(ConfigEncryptAESProvider.class);
+
+	@Override
+	public String encrypt(String content, String password) {
+		try {
+			return EncryptAlgorithm.AES256.encrypt(content, password);
+		}
+		catch (Exception e) {
+			log.error("[SCTT Config] Error on encrypting.", e);
+			throw e;
+		}
+	}
+
+	@Override
+	public String decrypt(String encryptedContent, String password) {
+		try {
+			return EncryptAlgorithm.AES256.decrypt(encryptedContent, password);
+		}
+		catch (Exception e) {
+			log.error("[SCTT Config] Error on decrypting.", e);
+			throw e;
+		}
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/ConfigEncryptProvider.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/ConfigEncryptProvider.java
new file mode 100644
index 000000000..e5cafca17
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/ConfigEncryptProvider.java
@@ -0,0 +1,44 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.config.tsf.encrypt;
+
+/**
+ * TSF 配置加密提供器接口.
+ *
+ * @author hongweizhu
+ */
+public abstract class ConfigEncryptProvider {
+
+	/**
+	 * 加密.
+	 *
+	 * @param content 明文
+	 * @param password 密码
+	 * @return 密文
+	 */
+	public abstract String encrypt(String content, String password);
+
+	/**
+	 * 解密.
+	 *
+	 * @param encryptedContent 密文
+	 * @param password 密码
+	 * @return 明文
+	 */
+	public abstract String decrypt(String encryptedContent, String password);
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/ConfigEncryptProviderFactory.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/ConfigEncryptProviderFactory.java
new file mode 100644
index 000000000..980417bb4
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/ConfigEncryptProviderFactory.java
@@ -0,0 +1,39 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.config.tsf.encrypt;
+
+public final class ConfigEncryptProviderFactory {
+
+	private static ConfigEncryptProvider configEncryptProvider = null;
+
+	private ConfigEncryptProviderFactory() {
+	}
+
+	public static ConfigEncryptProvider getInstance() {
+		if (null == configEncryptProvider) {
+			try {
+				Class<?> providerClass = Class.forName(EncryptConfig.getProviderClass());
+				configEncryptProvider = (ConfigEncryptProvider) providerClass.newInstance();
+			}
+			catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+				e.printStackTrace();
+			}
+		}
+		return configEncryptProvider;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/EncryptAlgorithm.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/EncryptAlgorithm.java
new file mode 100644
index 000000000..9a7959930
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/EncryptAlgorithm.java
@@ -0,0 +1,146 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.config.tsf.encrypt;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.Security;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.util.encoders.Base64;
+
+public class EncryptAlgorithm {
+	public static class AES256 {
+
+		/**
+		 * 加密.
+		 *
+		 * @param content 明文
+		 * @param password 密钥
+		 * @return 密文
+		 */
+		public static final String encrypt(String content, String password) {
+			if (null == password || "".equals(password)) {
+				throw new PasswordNotFoundException();
+			}
+			try {
+				// AES SK生成器
+				KeyGenerator kgen = KeyGenerator.getInstance("AES");
+				// SHA-256摘要密钥后生成安全随机数
+				SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
+				sr.setSeed(SHA256.encode(password));
+				kgen.init(256, sr);
+				// 生成秘密(对称)密钥
+				SecretKey secretKey = kgen.generateKey();
+				// 返回基本编码格式的密钥
+				byte[] enCodeFormat = secretKey.getEncoded();
+				// 根据给定的字节数组构造一个密钥。enCodeFormat:密钥内容;"AES":与给定的密钥内容相关联的密钥算法的名称
+				SecretKeySpec skSpec = new SecretKeySpec(enCodeFormat, "AES");
+				// 将提供程序添加到下一个可用位置
+				Security.addProvider(new BouncyCastleProvider());
+				// 创建一个实现指定转换的 Cipher对象,该转换由指定的提供程序提供。
+				// "AES/ECB/PKCS7Padding":转换的名称;"BC":提供程序的名称
+				Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
+				// 初始化cipher:加密模式
+				cipher.init(Cipher.ENCRYPT_MODE, skSpec);
+				byte[] byteContent = content.getBytes(StandardCharsets.UTF_8);
+				byte[] cryptograph = cipher.doFinal(byteContent);
+				byte[] enryptedContent = Base64.encode(cryptograph);
+				return new String(enryptedContent);
+			}
+			catch (Exception e) {
+				throw new RuntimeException("[SCTT Encrypt] Failed encrypt.", e);
+			}
+		}
+
+		/**
+		 * 解密.
+		 *
+		 * @param encryptedContent 密文
+		 * @param password 密钥
+		 * @return 明文
+		 */
+		public static final String decrypt(String encryptedContent, String password) {
+			if (null == password || "".equals(password)) {
+				throw new PasswordNotFoundException();
+			}
+			try {
+				// AES SK生成器
+				KeyGenerator kgen = KeyGenerator.getInstance("AES");
+				// SHA-256摘要密钥后生成安全随机数
+				SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
+				sr.setSeed(SHA256.encode(password));
+				kgen.init(256, sr);
+				// 生成秘密(对称)密钥
+				SecretKey secretKey = kgen.generateKey();
+				// 返回基本编码格式的密钥
+				byte[] enCodeFormat = secretKey.getEncoded();
+				// 根据给定的字节数组构造一个密钥。enCodeFormat:密钥内容;"AES":与给定的密钥内容相关联的密钥算法的名称
+				SecretKeySpec skSpec = new SecretKeySpec(enCodeFormat, "AES");
+				// 将提供程序添加到下一个可用位置
+				Security.addProvider(new BouncyCastleProvider());
+				// 创建一个实现指定转换的 Cipher对象,该转换由指定的提供程序提供。
+				// "AES/ECB/PKCS7Padding":转换的名称;"BC":提供程序的名称
+				Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
+				// 初始化cipher:解密模式
+				cipher.init(Cipher.DECRYPT_MODE, skSpec);
+				byte[] result = cipher.doFinal(Base64.decode(encryptedContent.getBytes(StandardCharsets.UTF_8)));
+				return new String(result);
+			}
+			catch (Exception e) {
+				throw new RuntimeException("[SCTT Encrypt] Failed decrypt.", e);
+			}
+		}
+	}
+
+	public static class SHA256 {
+
+		/**
+		 * 计算SHA-256摘要.
+		 *
+		 * @param content 原文
+		 * @return 摘要
+		 * @throws NoSuchAlgorithmException 算法不存在时抛出
+		 */
+		public static byte[] encode(String content) throws NoSuchAlgorithmException {
+			MessageDigest digester = MessageDigest.getInstance("SHA-256");
+			digester.update(content.getBytes(StandardCharsets.UTF_8));
+			return digester.digest();
+		}
+	}
+
+	public static class PasswordNotFoundException extends RuntimeException {
+
+		/**
+		 * serialVersionUID.
+		 */
+		private static final long serialVersionUID = -2843758461182470411L;
+
+		public PasswordNotFoundException() {
+			super("[SCTT Encrypt] Password not found.");
+		}
+
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/EncryptConfig.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/EncryptConfig.java
new file mode 100644
index 000000000..113317be1
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/tsf/encrypt/EncryptConfig.java
@@ -0,0 +1,114 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.config.tsf.encrypt;
+
+import org.springframework.util.StringUtils;
+
+public final class EncryptConfig {
+
+	private static final String PASSWORD_KEY = "tsf_config_encrypt_password";
+	/**
+	 * 加密前缀.
+	 */
+	public static String ENCRYPT_PREFIX = "ENC(";
+	/**
+	 * 加密后缀.
+	 */
+	public static String ENCRYPT_SUFFIX = ")";
+	/**
+	 * 密码.
+	 */
+	private static String password;
+	/**
+	 * 加解密提供器类名.
+	 */
+	private static String providerClass = "com.tencent.cloud.tsf.config.encrypt.ConfigEncryptAESProvider";
+
+	static {
+		// 环境变量
+		if (null != System.getenv(PASSWORD_KEY)) {
+			password = System.getenv(PASSWORD_KEY);
+		}
+		// JVM参数
+		if (null != System.getProperty(PASSWORD_KEY)) {
+			password = System.getProperty(PASSWORD_KEY);
+		}
+	}
+
+	private EncryptConfig() {
+
+	}
+
+	/**
+	 * 是否开启配置,判断 password 是否为空.
+	 */
+	public static Boolean getEnabled() {
+		return !StringUtils.isEmpty(password);
+	}
+
+	public static String getPassword() {
+		return EncryptConfig.password;
+	}
+
+	public static void setPassword(String password) {
+		EncryptConfig.password = password;
+	}
+
+	public static ConfigEncryptProvider getProvider() {
+		return ConfigEncryptProviderFactory.getInstance();
+	}
+
+	public static String getProviderClass() {
+		return providerClass;
+	}
+
+	public static void setProviderClass(String providerClass) {
+		EncryptConfig.providerClass = providerClass;
+	}
+
+	/**
+	 * 是否需要进行解密.
+	 *
+	 * @param content 判断对象
+	 * @return true:需要解密;false:不需要解密
+	 */
+	public static Boolean needDecrypt(Object content) {
+		if (null == content) {
+			return false;
+		}
+		else {
+			String stringValue = String.valueOf(content);
+			return stringValue.startsWith(ENCRYPT_PREFIX) && stringValue.endsWith(ENCRYPT_SUFFIX);
+		}
+	}
+
+	/**
+	 * 获取真实密文.
+	 *
+	 * @param content 原始配置值
+	 * @return 真实密文
+	 */
+	public static String realContent(Object content) {
+		if (null != content) {
+			String stringValue = String.valueOf(content);
+			return stringValue.substring(ENCRYPT_PREFIX.length(), stringValue.length() - ENCRYPT_SUFFIX.length());
+		}
+		return null;
+	}
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/ConfigChangeCallback.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/ConfigChangeCallback.java
new file mode 100644
index 000000000..8845ac391
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/ConfigChangeCallback.java
@@ -0,0 +1,28 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.tsf.consul.config.watch;
+
+public interface ConfigChangeCallback {
+
+	/**
+	 * 配置变更回调函数.
+	 * @param lastConfigProperty 旧的配置属性
+	 * @param newConfigProperty 新的配置属性
+	 */
+	void callback(ConfigProperty lastConfigProperty, ConfigProperty newConfigProperty);
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/ConfigChangeListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/ConfigChangeListener.java
new file mode 100644
index 000000000..7f5115384
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/ConfigChangeListener.java
@@ -0,0 +1,40 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.tsf.consul.config.watch;
+
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.stereotype.Component;
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Component
+public @interface ConfigChangeListener {
+	String prefix() default "";
+
+	String[] value() default {};
+
+	boolean async() default false;
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/ConfigProperty.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/ConfigProperty.java
new file mode 100644
index 000000000..45418efb1
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/ConfigProperty.java
@@ -0,0 +1,46 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.tsf.consul.config.watch;
+
+public class ConfigProperty {
+
+	private String key;
+
+	private Object value;
+
+	public ConfigProperty(String key, Object value) {
+		this.key = key;
+		this.value = value;
+	}
+
+	public String getKey() {
+		return key;
+	}
+
+	public void setKey(String key) {
+		this.key = key;
+	}
+
+	public Object getValue() {
+		return value;
+	}
+
+	public void setValue(Object value) {
+		this.value = value;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/TsfConsulConfigRefreshEventListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/TsfConsulConfigRefreshEventListener.java
new file mode 100644
index 000000000..688ffbe93
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/tsf/consul/config/watch/TsfConsulConfigRefreshEventListener.java
@@ -0,0 +1,122 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.tsf.consul.config.watch;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.tencent.cloud.polaris.config.listener.ConfigChangeEvent;
+import com.tencent.cloud.polaris.config.listener.PolarisConfigListenerContext;
+import com.tencent.cloud.polaris.config.listener.SyncConfigChangeListener;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.core.Ordered;
+import org.springframework.core.PriorityOrdered;
+import org.springframework.lang.NonNull;
+import org.springframework.util.StringUtils;
+
+public class TsfConsulConfigRefreshEventListener implements BeanPostProcessor, PriorityOrdered {
+	private static final String DOT = ".";
+
+	@Override
+	public int getOrder() {
+		return Ordered.LOWEST_PRECEDENCE;
+	}
+
+	@Override
+	public Object postProcessBeforeInitialization(@NonNull Object obj, @NonNull String beanName) throws BeansException {
+		return obj;
+	}
+
+	@Override
+	public Object postProcessAfterInitialization(@NonNull Object obj, @NonNull String beanName) throws BeansException {
+		Class<?> clz = obj.getClass();
+		if (!clz.isAnnotationPresent(ConfigChangeListener.class) || !ConfigChangeCallback.class.isAssignableFrom(clz)) {
+			return obj;
+		}
+
+		ConfigChangeListener targetAnno = clz.getAnnotation(ConfigChangeListener.class);
+		String watchedPrefix = targetAnno.prefix();
+		String[] watchedConfirmedValue = targetAnno.value();
+		boolean isAsync = targetAnno.async();
+		if (watchedConfirmedValue.length == 0 && StringUtils.isEmpty(watchedPrefix)) {
+			return obj;
+		}
+
+		ConfigChangeCallback bean = (ConfigChangeCallback) obj;
+		com.tencent.cloud.polaris.config.listener.ConfigChangeListener listener = new SyncConfigChangeListener() {
+			@Override
+			public void onChange(ConfigChangeEvent changeEvent) {
+				List<TsfCallbackParam> paramList = parseConfigChangeEventToTsfCallbackParam(changeEvent);
+				for (TsfCallbackParam param : paramList) {
+					if (isAsync()) {
+						PolarisConfigListenerContext.executor()
+								.execute(() -> bean.callback(param.oldValue, param.newValue));
+					}
+					else {
+						bean.callback(param.oldValue, param.newValue);
+					}
+				}
+			}
+
+			@Override
+			public boolean isAsync() {
+				return isAsync;
+			}
+		};
+
+		Set<String> interestedKeys = new HashSet<>();
+		Set<String> interestedKeyPrefixes = new HashSet<>();
+		if (watchedConfirmedValue.length > 0) {
+			for (String value : watchedConfirmedValue) {
+				interestedKeys.add(StringUtils.isEmpty(watchedPrefix) ? value : watchedPrefix + DOT + value);
+			}
+		}
+		else {
+			interestedKeyPrefixes.add(watchedPrefix);
+		}
+
+		PolarisConfigListenerContext.addChangeListener(listener, interestedKeys, interestedKeyPrefixes);
+		return bean;
+	}
+
+	private List<TsfCallbackParam> parseConfigChangeEventToTsfCallbackParam(ConfigChangeEvent event) {
+		List<TsfCallbackParam> result = new ArrayList<>();
+		Set<String> changedKeys = event.changedKeys();
+		for (String changedKey : changedKeys) {
+			ConfigProperty oldValue = new ConfigProperty(changedKey, event.getChange(changedKey).getOldValue());
+			ConfigProperty newValue = new ConfigProperty(changedKey, event.getChange(changedKey).getNewValue());
+			TsfCallbackParam param = new TsfCallbackParam(oldValue, newValue);
+			result.add(param);
+		}
+		return result;
+	}
+
+	static class TsfCallbackParam {
+		ConfigProperty oldValue;
+		ConfigProperty newValue;
+
+		TsfCallbackParam(ConfigProperty oldValue, ConfigProperty newValue) {
+			this.oldValue = oldValue;
+			this.newValue = newValue;
+		}
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/services/com.tencent.cloud.polaris.config.adapter.PolarisConfigCustomExtensionLayer b/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/services/com.tencent.cloud.polaris.config.adapter.PolarisConfigCustomExtensionLayer
new file mode 100644
index 000000000..427220a36
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/services/com.tencent.cloud.polaris.config.adapter.PolarisConfigCustomExtensionLayer
@@ -0,0 +1 @@
+com.tencent.cloud.polaris.config.tsf.adaptor.PolarisAdaptorTsfConfigExtensionLayer
diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories
index 98221a39a..10aa4fc37 100644
--- a/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-starter-tencent-polaris-config/src/main/resources/META-INF/spring.factories
@@ -1,5 +1,9 @@
-org.springframework.cloud.bootstrap.BootstrapConfiguration=\
-  com.tencent.cloud.polaris.config.PolarisConfigBootstrapAutoConfiguration
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  com.tencent.cloud.polaris.config.tsf.PolarisAdaptorTsfConfigAutoConfiguration,\
   com.tencent.cloud.polaris.config.PolarisConfigAutoConfiguration,\
   com.tencent.cloud.polaris.config.endpoint.PolarisConfigEndpointAutoConfiguration
+org.springframework.cloud.bootstrap.BootstrapConfiguration=\
+  com.tencent.cloud.polaris.config.PolarisConfigBootstrapAutoConfiguration,\
+  com.tencent.cloud.polaris.config.tsf.PolarisAdaptorTsfConfigBootstrapConfiguration
+
+
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfApiMetadataGrapher.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfApiMetadataGrapher.java
new file mode 100644
index 000000000..4278d7093
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfApiMetadataGrapher.java
@@ -0,0 +1,137 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.contract.tsf;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.tencent.cloud.common.util.GzipUtil;
+import io.swagger.v3.oas.models.OpenAPI;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springdoc.api.AbstractOpenApiResource;
+import org.springdoc.api.AbstractOpenApiResourceUtil;
+import org.springdoc.core.providers.ObjectMapperProvider;
+import org.springdoc.webflux.api.OpenApiWebFluxUtil;
+import org.springdoc.webmvc.api.OpenApiWebMvcUtil;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.SmartLifecycle;
+import org.springframework.core.env.Environment;
+import org.springframework.util.StringUtils;
+
+public class TsfApiMetadataGrapher implements SmartLifecycle {
+
+	private final AtomicBoolean isRunning = new AtomicBoolean(false);
+	private final org.springdoc.webmvc.api.MultipleOpenApiResource multipleOpenApiWebMvcResource;
+	private final org.springdoc.webflux.api.MultipleOpenApiResource multipleOpenApiWebFluxResource;
+	private final ObjectMapperProvider springdocObjectMapperProvider;
+	private Logger logger = LoggerFactory.getLogger(TsfApiMetadataGrapher.class);
+	private ApplicationContext applicationContext;
+	private String groupName;
+
+	public TsfApiMetadataGrapher(org.springdoc.webmvc.api.MultipleOpenApiResource multipleOpenApiWebMvcResource,
+			org.springdoc.webflux.api.MultipleOpenApiResource multipleOpenApiWebFluxResource,
+			String groupName, ApplicationContext applicationContext, ObjectMapperProvider springdocObjectMapperProvider) {
+		this.applicationContext = applicationContext;
+		this.multipleOpenApiWebMvcResource = multipleOpenApiWebMvcResource;
+		this.multipleOpenApiWebFluxResource = multipleOpenApiWebFluxResource;
+		this.groupName = groupName;
+		this.springdocObjectMapperProvider = springdocObjectMapperProvider;
+	}
+
+	@Override
+	public boolean isAutoStartup() {
+		return true;
+	}
+
+	@Override
+	public void stop(Runnable runnable) {
+		runnable.run();
+		stop();
+	}
+
+	@Override
+	public void start() {
+		if (!isRunning.compareAndSet(false, true)) {
+			return;
+		}
+		try {
+			AbstractOpenApiResource openApiResource = null;
+			if (multipleOpenApiWebMvcResource != null) {
+				openApiResource = OpenApiWebMvcUtil.getOpenApiResourceOrThrow(multipleOpenApiWebMvcResource, groupName);
+			}
+			else if (multipleOpenApiWebFluxResource != null) {
+				openApiResource = OpenApiWebFluxUtil.getOpenApiResourceOrThrow(multipleOpenApiWebFluxResource, groupName);
+			}
+			OpenAPI openAPI = null;
+			if (openApiResource != null) {
+				openAPI = AbstractOpenApiResourceUtil.getOpenApi(openApiResource);
+			}
+			String jsonValue;
+			if (springdocObjectMapperProvider != null && springdocObjectMapperProvider.jsonMapper() != null) {
+				jsonValue = springdocObjectMapperProvider.jsonMapper().writeValueAsString(openAPI);
+			}
+			else {
+				ObjectMapper mapper = new ObjectMapper();
+				mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+				jsonValue = mapper.writeValueAsString(openAPI);
+			}
+			if (openAPI != null && !StringUtils.isEmpty(jsonValue)) {
+				String serviceApiMeta = GzipUtil.compressBase64Encode(jsonValue, "utf-8");
+				Environment environment = applicationContext.getEnvironment();
+				String tsfToken = environment.getProperty("tsf_token");
+				String tsfGroupId = environment.getProperty("tsf_group_id");
+				if (StringUtils.isEmpty(tsfGroupId) || StringUtils.isEmpty(tsfToken)) {
+					logger.info("[tsf-swagger] auto smart check application start with local consul, api registry not work");
+					return;
+				}
+				logger.info("[tsf-swagger] api_meta len: {}", serviceApiMeta.length());
+				String applicationName = environment.getProperty("spring.application.name");
+				if (logger.isDebugEnabled()) {
+					logger.debug("[tsf-swagger] service: {} openApi json data: {}", applicationName, jsonValue);
+					logger.debug("[tsf-swagger] service: {} api_meta info: {}", applicationName, serviceApiMeta);
+				}
+
+				System.setProperty(String.format("$%s", "api_metas"), serviceApiMeta);
+			}
+			else {
+				logger.warn("[tsf-swagger] swagger or json is null, openApiResource keys:{}, group:{}", openApiResource, groupName);
+			}
+		}
+		catch (Throwable t) {
+			logger.error("[tsf swagger] init TsfApiMetadataGrapher failed. occur exception: ", t);
+		}
+	}
+
+	@Override
+	public void stop() {
+		isRunning.set(true);
+	}
+
+	@Override
+	public boolean isRunning() {
+		return isRunning.get();
+	}
+
+	@Override
+	public int getPhase() {
+		return -2;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfContractProperties.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfContractProperties.java
new file mode 100644
index 000000000..74e48d801
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfContractProperties.java
@@ -0,0 +1,136 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.contract.tsf;
+
+import com.tencent.cloud.polaris.contract.config.ExtendedContractProperties;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Properties for TSF contract.
+ *
+ * @author Haotian Zhang
+ */
+@ConfigurationProperties("tsf.swagger")
+public class TsfContractProperties implements ExtendedContractProperties {
+
+	@Value("${tsf.swagger.basePackage:}")
+	private String basePackage;
+
+	@Value("${tsf.swagger.excludePath:}")
+	private String excludePath;
+
+	@Value("${tsf.swagger.enabled:true}")
+	private boolean enabled;
+
+	@Value("${tsf.swagger.group:default}")
+	private String groupName;
+
+	@Value("${tsf.swagger.basePath:/**}")
+	private String basePath;
+
+	@Value("${tsf.swagger.doc.auto-startup:true}")
+	private boolean exposure;
+
+	/**
+	 * applicationId 应用Id.
+	 */
+	@Value("${tsf_application_id:}")
+	private String name;
+
+	@Override
+	public boolean isEnabled() {
+		return enabled;
+	}
+
+	@Override
+	public void setEnabled(boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	@Override
+	public String getBasePackage() {
+		return basePackage;
+	}
+
+	@Override
+	public void setBasePackage(String basePackage) {
+		this.basePackage = basePackage;
+	}
+
+	@Override
+	public String getExcludePath() {
+		return excludePath;
+	}
+
+	@Override
+	public void setExcludePath(String excludePath) {
+		this.excludePath = excludePath;
+	}
+
+	@Override
+	public String getGroup() {
+		return groupName;
+	}
+
+	@Override
+	public void setGroup(String group) {
+		this.groupName = group;
+	}
+
+	@Override
+	public String getBasePath() {
+		return basePath;
+	}
+
+	@Override
+	public void setBasePath(String basePath) {
+		this.basePath = basePath;
+	}
+
+	@Override
+	public boolean isExposure() {
+		return exposure;
+	}
+
+	@Override
+	public void setExposure(boolean exposure) {
+		this.exposure = exposure;
+	}
+
+	@Override
+	public boolean isReportEnabled() {
+		return enabled;
+	}
+
+	@Override
+	public void setReportEnabled(boolean reportEnabled) {
+
+	}
+
+	@Override
+	public String getName() {
+		return name;
+	}
+
+	@Override
+	public void setName(String name) {
+		this.name = name;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfContractPropertiesAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfContractPropertiesAutoConfiguration.java
new file mode 100644
index 000000000..79b75875a
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfContractPropertiesAutoConfiguration.java
@@ -0,0 +1,40 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.contract.tsf;
+
+import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Auto configuration for TSF contract properties.
+ *
+ * @author Haotian Zhang
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnTsfEnabled
+public class TsfContractPropertiesAutoConfiguration {
+
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfContractProperties tsfContractProperties() {
+		return new TsfContractProperties();
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfContractPropertiesBootstrapConfiguration.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfContractPropertiesBootstrapConfiguration.java
new file mode 100644
index 000000000..56cf5b3be
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfContractPropertiesBootstrapConfiguration.java
@@ -0,0 +1,35 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.contract.tsf;
+
+import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * Bootstrap configuration for TSF contract properties.
+ *
+ * @author Haotian Zhang
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnTsfEnabled
+@Import(TsfContractPropertiesAutoConfiguration.class)
+public class TsfContractPropertiesBootstrapConfiguration {
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfSwaggerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfSwaggerAutoConfiguration.java
new file mode 100644
index 000000000..e066a97c7
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/java/com/tencent/cloud/polaris/contract/tsf/TsfSwaggerAutoConfiguration.java
@@ -0,0 +1,50 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package com.tencent.cloud.polaris.contract.tsf;
+
+import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
+import com.tencent.cloud.polaris.contract.config.PolarisContractProperties;
+import io.swagger.v3.oas.models.OpenAPI;
+import org.springdoc.core.providers.ObjectMapperProvider;
+import org.springdoc.webflux.api.MultipleOpenApiWebFluxResource;
+import org.springdoc.webmvc.api.MultipleOpenApiWebMvcResource;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.lang.Nullable;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+
+@EnableWebMvc
+@Configuration
+@ConditionalOnTsfEnabled
+@ConditionalOnClass(name = "org.springframework.web.servlet.config.annotation.EnableWebMvc")
+@ConditionalOnProperty(value = "tsf.swagger.enabled", havingValue = "true", matchIfMissing = true)
+public class TsfSwaggerAutoConfiguration {
+
+	@Bean
+	@ConditionalOnBean(OpenAPI.class)
+	public TsfApiMetadataGrapher tsfApiMetadataGrapher(@Nullable MultipleOpenApiWebMvcResource multipleOpenApiWebMvcResource,
+			@Nullable MultipleOpenApiWebFluxResource multipleOpenApiWebFluxResource, ApplicationContext context,
+			PolarisContractProperties polarisContractProperties, ObjectMapperProvider springdocObjectMapperProvider) {
+		return new TsfApiMetadataGrapher(multipleOpenApiWebMvcResource, multipleOpenApiWebFluxResource,
+				polarisContractProperties.getGroup(), context, springdocObjectMapperProvider);
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/spring.factories
index 406e1aba4..5b6d4736e 100644
--- a/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-starter-tencent-polaris-contract/src/main/resources/META-INF/spring.factories
@@ -1,8 +1,11 @@
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
   com.tencent.cloud.polaris.contract.config.PolarisSwaggerAutoConfiguration,\
   com.tencent.cloud.polaris.contract.config.PolarisContractProperties,\
-    com.tencent.cloud.polaris.contract.config.PolarisContractPropertiesAutoConfiguration
+  com.tencent.cloud.polaris.contract.config.PolarisContractPropertiesAutoConfiguration,\
+  com.tencent.cloud.polaris.contract.tsf.TsfContractPropertiesAutoConfiguration,\
+  com.tencent.cloud.polaris.contract.tsf.TsfSwaggerAutoConfiguration
 org.springframework.cloud.bootstrap.BootstrapConfiguration=\
-  com.tencent.cloud.polaris.contract.config.PolarisContractPropertiesBootstrapConfiguration
+  com.tencent.cloud.polaris.contract.config.PolarisContractPropertiesBootstrapConfiguration,\
+  com.tencent.cloud.polaris.contract.tsf.TsfContractPropertiesBootstrapConfiguration
 org.springframework.context.ApplicationListener=\
   com.tencent.cloud.polaris.contract.PolarisSwaggerApplicationListener
diff --git a/spring-cloud-starter-tencent-polaris-discovery/pom.xml b/spring-cloud-starter-tencent-polaris-discovery/pom.xml
index 62ff58198..6e0ec3146 100644
--- a/spring-cloud-starter-tencent-polaris-discovery/pom.xml
+++ b/spring-cloud-starter-tencent-polaris-discovery/pom.xml
@@ -19,18 +19,17 @@
 			<groupId>com.tencent.cloud</groupId>
 			<artifactId>spring-cloud-tencent-rpc-enhancement</artifactId>
 		</dependency>
-		<!-- Spring Cloud Tencent dependencies end -->
 
-		<!-- Polaris dependencies start -->
 		<dependency>
-			<groupId>com.tencent.polaris</groupId>
-			<artifactId>polaris-test-common</artifactId>
-			<scope>test</scope>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-tencent-lossless-plugin</artifactId>
 		</dependency>
+		<!-- Spring Cloud Tencent dependencies end -->
 
+		<!-- Polaris dependencies start -->
 		<dependency>
 			<groupId>com.tencent.polaris</groupId>
-			<artifactId>connector-consul</artifactId>
+			<artifactId>polaris-test-common</artifactId>
 			<scope>test</scope>
 		</dependency>
 
@@ -83,6 +82,11 @@
 			<optional>true</optional>
 		</dependency>
 
+		<dependency>
+			<groupId>joda-time</groupId>
+			<artifactId>joda-time</artifactId>
+		</dependency>
+
 		<dependency>
 			<groupId>org.mockito</groupId>
 			<artifactId>mockito-inline</artifactId>
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java
index 80b17a1c2..12d444a64 100644
--- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java
@@ -135,8 +135,8 @@ public class PolarisServiceRegistry implements ServiceRegistry<PolarisRegistrati
 				heartbeat(heartbeatRequest);
 			}
 			registration.setInstanceId(instanceRegisterResponse.getInstanceId());
-			LOGGER.info("polaris registry, {} {} {}:{} {} register finished", polarisDiscoveryProperties.getNamespace(),
-					registration.getServiceId(), registration.getHost(), registration.getPort(),
+			LOGGER.info("polaris registry, {} {} {} {}:{} {} register finished", polarisDiscoveryProperties.getNamespace(),
+					registration.getServiceId(), registration.getInstanceId(), registration.getHost(), registration.getPort(),
 					staticMetadataManager.getMergedStaticMetadata());
 			if (Objects.nonNull(polarisStatProperties) && polarisStatProperties.isEnabled()) {
 				try {
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryConfigModifier.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryConfigModifier.java
new file mode 100644
index 000000000..d20774205
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryConfigModifier.java
@@ -0,0 +1,193 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+
+import com.tencent.cloud.common.constant.OrderConstant;
+import com.tencent.cloud.common.util.JacksonUtils;
+import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
+import com.tencent.cloud.polaris.context.PolarisConfigModifier;
+import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
+import com.tencent.cloud.polaris.context.tsf.config.TsfCoreProperties;
+import com.tencent.cloud.polaris.context.tsf.consul.TsfConsulProperties;
+import com.tencent.cloud.polaris.tsf.util.RegistrationUtil;
+import com.tencent.polaris.api.config.plugin.DefaultPlugins;
+import com.tencent.polaris.factory.config.ConfigurationImpl;
+import com.tencent.polaris.factory.config.consumer.DiscoveryConfigImpl;
+import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl;
+import com.tencent.polaris.factory.config.provider.RegisterConfigImpl;
+import com.tencent.polaris.plugins.connector.common.constant.ConsulConstant;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * Modifier for TSF discovery.
+ *
+ * @author Haotian Zhang
+ */
+public class TsfDiscoveryConfigModifier implements PolarisConfigModifier {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(TsfDiscoveryConfigModifier.class);
+
+	private final TsfCoreProperties tsfCoreProperties;
+	private final TsfConsulProperties tsfConsulProperties;
+	private final TsfDiscoveryProperties tsfDiscoveryProperties;
+
+	private final TsfHeartbeatProperties tsfHeartbeatProperties;
+
+	private final PolarisDiscoveryProperties polarisDiscoveryProperties;
+
+	private final PolarisContextProperties polarisContextProperties;
+	private final ApplicationContext context;
+
+	public TsfDiscoveryConfigModifier(TsfCoreProperties tsfCoreProperties, TsfConsulProperties tsfConsulProperties,
+			TsfDiscoveryProperties tsfDiscoveryProperties, TsfHeartbeatProperties tsfHeartbeatProperties,
+			PolarisDiscoveryProperties polarisDiscoveryProperties, PolarisContextProperties polarisContextProperties, ApplicationContext context) {
+		this.tsfCoreProperties = tsfCoreProperties;
+		this.tsfConsulProperties = tsfConsulProperties;
+		this.tsfDiscoveryProperties = tsfDiscoveryProperties;
+		this.tsfHeartbeatProperties = tsfHeartbeatProperties;
+		this.polarisDiscoveryProperties = polarisDiscoveryProperties;
+		this.polarisContextProperties = polarisContextProperties;
+		this.context = context;
+	}
+
+	@Override
+	public void modify(ConfigurationImpl configuration) {
+		// namespace id
+		polarisDiscoveryProperties.setHeartbeatInterval(Long.valueOf(tsfHeartbeatProperties.computeHearbeatInterval()
+				.toStandardDuration().getMillis()).intValue());
+		polarisContextProperties.setNamespace(tsfDiscoveryProperties.getTsfNamespaceId());
+		polarisDiscoveryProperties.setNamespace(tsfDiscoveryProperties.getTsfNamespaceId());
+		System.setProperty("spring.cloud.polaris.namespace", tsfDiscoveryProperties.getTsfNamespaceId());
+
+		// application id
+		polarisDiscoveryProperties.setVersion(tsfDiscoveryProperties.getTsfProgVersion());
+
+		// instance id
+		polarisDiscoveryProperties.setInstanceId(tsfDiscoveryProperties.getInstanceId());
+
+		boolean consulEnable = tsfCoreProperties.isTsfConsulEnable();
+		boolean polarisEnable = tsfCoreProperties.isTsePolarisEnable();
+
+		// 删除可能存在的consul connector配置
+		if (!CollectionUtils.isEmpty(configuration.getGlobal().getServerConnectors())) {
+			for (ServerConnectorConfigImpl config : configuration.getGlobal().getServerConnectors()) {
+				if (StringUtils.equals(config.getId(), RegistrationUtil.ID)) {
+					configuration.getGlobal().getServerConnectors().remove(config);
+				}
+			}
+		}
+		else {
+			configuration.getGlobal().setServerConnectors(new ArrayList<>());
+		}
+		// 删除可能存在的consul发现配置
+		for (DiscoveryConfigImpl dc : configuration.getConsumer().getDiscoveries()) {
+			if (StringUtils.equals(dc.getServerConnectorId(), RegistrationUtil.ID)) {
+				configuration.getConsumer().getDiscoveries().remove(dc);
+			}
+		}
+		// 删除可能存在的consul注册配置
+		for (RegisterConfigImpl rc : configuration.getProvider().getRegisters()) {
+			if (StringUtils.equals(rc.getServerConnectorId(), RegistrationUtil.ID)) {
+				configuration.getProvider().getRegisters().remove(rc);
+			}
+		}
+
+		// 如果ServerConnectors为空,则把ServerConnector(如有)复制过去
+		if (CollectionUtils.isEmpty(configuration.getGlobal().getServerConnectors())
+				&& null != configuration.getGlobal().getServerConnector()) {
+			configuration.getGlobal().getServerConnectors().add(configuration.getGlobal().getServerConnector());
+		}
+		if (consulEnable) {
+			// enable consul
+			ServerConnectorConfigImpl serverConnectorConfig = new ServerConnectorConfigImpl();
+			serverConnectorConfig.setId(RegistrationUtil.ID);
+			serverConnectorConfig.setAddresses(
+					Collections.singletonList(tsfConsulProperties.getHost() + ":" + tsfConsulProperties.getPort()));
+			LOGGER.info("Will register to consul server: [" + tsfConsulProperties.getHost() + ":" + tsfConsulProperties.getPort() + "]");
+			serverConnectorConfig.setProtocol(DefaultPlugins.SERVER_CONNECTOR_CONSUL);
+
+			Map<String, String> metadata = serverConnectorConfig.getMetadata();
+			String appName = RegistrationUtil.getAppName(tsfDiscoveryProperties, context.getEnvironment());
+			metadata.put(ConsulConstant.MetadataMapKey.SERVICE_NAME_KEY, RegistrationUtil.normalizeForDns(appName));
+			metadata.put(ConsulConstant.MetadataMapKey.INSTANCE_ID_KEY, RegistrationUtil.getInstanceId(tsfDiscoveryProperties, context));
+			if (StringUtils.isNotBlank(tsfDiscoveryProperties.getAclToken())) {
+				serverConnectorConfig.setToken(tsfDiscoveryProperties.getAclToken());
+			}
+			metadata.put(ConsulConstant.MetadataMapKey.TAGS_KEY, JacksonUtils.serialize2Json(RegistrationUtil.createTags(tsfDiscoveryProperties)));
+			if (StringUtils.isNotBlank(tsfDiscoveryProperties.getDefaultQueryTag())) {
+				metadata.put(ConsulConstant.MetadataMapKey.QUERY_TAG_KEY, tsfDiscoveryProperties.getDefaultQueryTag());
+			}
+			metadata.put(ConsulConstant.MetadataMapKey.QUERY_PASSING_KEY, String.valueOf(tsfDiscoveryProperties.isQueryPassing()));
+			if (tsfDiscoveryProperties.isPreferIpAddress()
+					&& StringUtils.isNotBlank(tsfDiscoveryProperties.getIpAddress())) {
+				metadata.put(ConsulConstant.MetadataMapKey.PREFER_IP_ADDRESS_KEY,
+						String.valueOf(tsfDiscoveryProperties.isPreferIpAddress()));
+				metadata.put(ConsulConstant.MetadataMapKey.IP_ADDRESS_KEY, tsfDiscoveryProperties.getIpAddress());
+			}
+			if (!tsfDiscoveryProperties.isPreferAgentAddress()) {
+				metadata.put(ConsulConstant.MetadataMapKey.PREFER_IP_ADDRESS_KEY,
+						String.valueOf(tsfDiscoveryProperties.isPreferIpAddress()));
+				metadata.put(ConsulConstant.MetadataMapKey.IP_ADDRESS_KEY, tsfDiscoveryProperties.getHostname());
+			}
+			configuration.getGlobal().getServerConnectors().add(serverConnectorConfig);
+
+			// 添加发现配置
+			DiscoveryConfigImpl discoveryConfig = new DiscoveryConfigImpl();
+			discoveryConfig.setServerConnectorId(RegistrationUtil.ID);
+			discoveryConfig.setEnable(tsfDiscoveryProperties.isEnabled());
+			configuration.getConsumer().getDiscoveries().add(discoveryConfig);
+
+			// 添加注册配置
+			RegisterConfigImpl registerConfig = new RegisterConfigImpl();
+			registerConfig.setServerConnectorId(RegistrationUtil.ID);
+			registerConfig.setEnable(tsfDiscoveryProperties.isRegister());
+			configuration.getProvider().getRegisters().add(registerConfig);
+		}
+
+		if (polarisDiscoveryProperties != null) {
+			if (!polarisEnable) {
+				configuration.getGlobal().getAPI().setReportEnable(false);
+				for (DiscoveryConfigImpl dc : configuration.getConsumer().getDiscoveries()) {
+					if (StringUtils.equals(dc.getServerConnectorId(), "polaris")) {
+						dc.setEnable(false);
+					}
+				}
+				for (RegisterConfigImpl rc : configuration.getProvider().getRegisters()) {
+					if (StringUtils.equals(rc.getServerConnectorId(), "polaris")) {
+						rc.setEnable(false);
+						rc.setReportServiceContractEnable(false);
+					}
+				}
+			}
+		}
+	}
+
+	@Override
+	public int getOrder() {
+		return OrderConstant.Modifier.CONSUL_DISCOVERY_CONFIG_ORDER + 1;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryProperties.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryProperties.java
new file mode 100644
index 000000000..7e2e1f92f
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryProperties.java
@@ -0,0 +1,744 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.tencent.cloud.common.util.inet.PolarisInetUtils;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.commons.util.InetUtils;
+
+/**
+ * Defines configuration for service discovery and registration.
+ *
+ * @author Spencer Gibb
+ * @author Donnabell Dmello
+ * @author Venil Noronha
+ * @author Richard Kettelerij
+ */
+@ConfigurationProperties("tsf.discovery")
+public class TsfDiscoveryProperties {
+
+	protected static final String MANAGEMENT = "management";
+
+	private InetUtils.HostInfo hostInfo;
+
+	@Value("${tsf_token:${consul.token:${CONSUL_TOKEN:${spring.cloud.consul.token:${SPRING_CLOUD_CONSUL_TOKEN:}}}}}")
+	private String aclToken;
+
+	/**
+	 * Tags to use when registering service.
+	 */
+	private List<String> tags = new ArrayList<>();
+
+	/**
+	 * If service discovery enabled.
+	 */
+	private boolean enabled = true;
+
+	/**
+	 * Tags to use when registering management service.
+	 */
+	private List<String> managementTags = new ArrayList<>();
+
+	/**
+	 * Alternate server path to invoke for health checking .
+	 */
+	private String healthCheckPath = "/actuator/health";
+
+	/**
+	 * Custom health check url to override default.
+	 */
+	private String healthCheckUrl;
+
+	/**
+	 * How often to perform the health check (e.g. 10s), defaults to 10s.
+	 */
+	private String healthCheckInterval = "10s";
+
+	/**
+	 * Timeout for health check (e.g. 10s).
+	 */
+	private String healthCheckTimeout;
+
+	/**
+	 * Timeout to deregister services critical for longer than timeout (e.g. 30m).
+	 * Requires consul version 7.x or higher.
+	 */
+	private String healthCheckCriticalTimeout;
+
+	/**
+	 * IP address to use when accessing service (must also set preferIpAddress to use).
+	 */
+	private String ipAddress;
+
+	/**
+	 * Hostname to use when accessing server.
+	 */
+	private String hostname;
+
+	/**
+	 * Port to register the service under (defaults to listening port).
+	 */
+	private Integer port;
+
+	/**
+	 * Port to register the management service under (defaults to management port).
+	 */
+	private Integer managementPort;
+
+	private Lifecycle lifecycle = new Lifecycle();
+
+	/**
+	 * Use ip address rather than hostname during registration.
+	 * 默认使用IP地址
+	 */
+	private boolean preferIpAddress = true;
+
+	/**
+	 * Source of how we will determine the address to use.
+	 */
+	private boolean preferAgentAddress = false;
+
+	/**
+	 * The delay between calls to watch consul catalog in millis, default is 1000.
+	 */
+	private int catalogServicesWatchDelay = 1000;
+
+	/**
+	 * The number of seconds to block while watching consul catalog, default is 2.
+	 */
+	private int catalogServicesWatchTimeout = 55;
+
+	/**
+	 * Service name.
+	 */
+	private String serviceName;
+
+	/**
+	 * Unique service instance id.
+	 */
+	@Value("${tsf_instance_id:${spring.cloud.consul.discovery.instanceId:${SPRING_CLOUD_CONSUL_DISCOVERY_INSTANCEID:}}}")
+	private String instanceId;
+
+	/**
+	 * Service instance zone.
+	 */
+	private String instanceZone;
+
+	/**
+	 * Service instance group.
+	 */
+	private String instanceGroup;
+
+	/**
+	 * Service instance zone comes from metadata.
+	 * This allows changing the metadata tag name.
+	 */
+	private String defaultZoneMetadataName = "zone";
+
+	/**
+	 * Whether to register an http or https service.
+	 */
+	private String scheme = "http";
+
+	/**
+	 * Suffix to use when registering management service.
+	 */
+	private String managementSuffix = MANAGEMENT;
+
+	/**
+	 * Map of serviceId's -> tag to query for in server list.
+	 * This allows filtering services by a single tag.
+	 */
+	private Map<String, String> serverListQueryTags = new HashMap<>();
+
+	/**
+	 * Map of serviceId's -> datacenter to query for in server list.
+	 * This allows looking up services in another datacenters.
+	 */
+	private Map<String, String> datacenters = new HashMap<>();
+
+	/**
+	 * Tag to query for in service list if one is not listed in serverListQueryTags.
+	 */
+	private String defaultQueryTag;
+
+	/**
+	 * Add the 'passing` parameter to /v1/health/service/serviceName.
+	 * This pushes health check passing to the server.
+	 */
+	private boolean queryPassing = true;
+
+	/**
+	 * Register as a service in consul.
+	 */
+	private boolean register = true;
+
+	/**
+	 * Disable automatic de-registration of service in consul.
+	 */
+	private boolean deregister = true;
+
+	/**
+	 * Register health check in consul. Useful during development of a service.
+	 */
+	private boolean registerHealthCheck = true;
+
+	/**
+	 * Throw exceptions during service registration if true, otherwise, log
+	 * warnings (defaults to true).
+	 */
+	private boolean failFast = true;
+
+	/**
+	 * Skips certificate verification during service checks if true, otherwise
+	 * runs certificate verification.
+	 */
+	private Boolean healthCheckTlsSkipVerify;
+
+	/**
+	 * tsf service consul registration tags.
+	 *
+	 * applicationId 应用Id
+	 */
+	@Value("${tsf_application_id:}")
+	private String tsfApplicationId;
+
+	/**
+	 * tsf service consul registration tags.
+	 *
+	 * groupId 部署组Id
+	 */
+	@Value("${tsf_group_id:}")
+	private String tsfGroupId;
+
+	/**
+	 * 仅本地测试时使用.
+	 */
+	@Value("${tsf_namespace_id:}")
+	private String tsfNamespaceId;
+
+	/**
+	 * tsf service consul registration tags.
+	 *
+	 * progVersion 包版本
+	 */
+	@Value("${tsf_prog_version:}")
+	private String tsfProgVersion;
+
+	/**
+	 * tsf service consul registration tags.
+	 *
+	 * 地域信息
+	 */
+	@Value("${tsf_region:}")
+	private String tsfRegion;
+
+	/**
+	 * tsf service consul registration tags.
+	 *
+	 * 可用区信息
+	 */
+	@Value("${tsf_zone:}")
+	private String tsfZone;
+
+	/**
+	 * 有状态服务回调的线程池.
+	 */
+	private int callbackPoolSize = 10;
+
+	private long callbackInitialDelay = 10 * 1000L;
+
+	private long callbackErrorDelay = 30 * 1000L;
+
+
+	/**
+	 * 是否开启零实例保护,默认开启。开启时如果 consul 返回在线实例为0,用上次的缓存(正常来说线上环境不应该有provider全下线的情况).
+	 * 定制化双发现时可能需要关闭,此时如果provider下线,则返回空列表。如果 consul 连接不上则用缓存.
+	 */
+	private boolean zeroInstanceProtect = true;
+
+	private int testConnectivityTimeout = 5000;
+
+	private Map<String, String> serviceMeta;
+
+	@SuppressWarnings("unused")
+	private TsfDiscoveryProperties() {
+		this.managementTags.add(MANAGEMENT);
+	}
+
+	public TsfDiscoveryProperties(PolarisInetUtils polarisInetUtils) {
+		this();
+		this.hostInfo = polarisInetUtils.findFirstNonLoopbackHostInfo();
+		this.ipAddress = this.hostInfo.getIpAddress();
+		this.hostname = this.hostInfo.getHostname();
+	}
+
+	/**
+	 * @param serviceId The service who's filtering tag is being looked up
+	 * @return The tag the given service id should be filtered by, or null.
+	 */
+	public String getQueryTagForService(String serviceId) {
+		String tag = serverListQueryTags.get(serviceId);
+		return tag != null ? tag : defaultQueryTag;
+	}
+
+	public String getHostname() {
+		return this.preferIpAddress ? this.ipAddress : this.hostname;
+	}
+
+	public void setHostname(String hostname) {
+		this.hostname = hostname;
+		this.hostInfo.override = true;
+	}
+
+	private InetUtils.HostInfo getHostInfo() {
+		return hostInfo;
+	}
+
+	private void setHostInfo(InetUtils.HostInfo hostInfo) {
+		this.hostInfo = hostInfo;
+	}
+
+	public String getAclToken() {
+		return aclToken;
+	}
+
+	public void setAclToken(String aclToken) {
+		this.aclToken = aclToken;
+	}
+
+	public List<String> getTags() {
+		return tags;
+	}
+
+	public void setTags(List<String> tags) {
+		this.tags = tags;
+	}
+
+	public boolean isEnabled() {
+		return enabled;
+	}
+
+	public void setEnabled(boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	public List<String> getManagementTags() {
+		return managementTags;
+	}
+
+	public void setManagementTags(List<String> managementTags) {
+		this.managementTags = managementTags;
+	}
+
+	public String getHealthCheckPath() {
+		return healthCheckPath;
+	}
+
+	public void setHealthCheckPath(String healthCheckPath) {
+		this.healthCheckPath = healthCheckPath;
+	}
+
+	public String getHealthCheckUrl() {
+		return healthCheckUrl;
+	}
+
+	public void setHealthCheckUrl(String healthCheckUrl) {
+		this.healthCheckUrl = healthCheckUrl;
+	}
+
+	public String getHealthCheckInterval() {
+		return healthCheckInterval;
+	}
+
+	public void setHealthCheckInterval(String healthCheckInterval) {
+		this.healthCheckInterval = healthCheckInterval;
+	}
+
+	public String getHealthCheckTimeout() {
+		return healthCheckTimeout;
+	}
+
+	public void setHealthCheckTimeout(String healthCheckTimeout) {
+		this.healthCheckTimeout = healthCheckTimeout;
+	}
+
+	public String getHealthCheckCriticalTimeout() {
+		return healthCheckCriticalTimeout;
+	}
+
+	public void setHealthCheckCriticalTimeout(String healthCheckCriticalTimeout) {
+		this.healthCheckCriticalTimeout = healthCheckCriticalTimeout;
+	}
+
+	public String getIpAddress() {
+		return ipAddress;
+	}
+
+	public void setIpAddress(String ipAddress) {
+		this.ipAddress = ipAddress;
+		this.hostInfo.override = true;
+	}
+
+	public Integer getPort() {
+		return port;
+	}
+
+	public void setPort(Integer port) {
+		this.port = port;
+	}
+
+	public Integer getManagementPort() {
+		return managementPort;
+	}
+
+	public void setManagementPort(Integer managementPort) {
+		this.managementPort = managementPort;
+	}
+
+	public Lifecycle getLifecycle() {
+		return lifecycle;
+	}
+
+	public void setLifecycle(Lifecycle lifecycle) {
+		this.lifecycle = lifecycle;
+	}
+
+	public boolean isPreferIpAddress() {
+		return preferIpAddress;
+	}
+
+	public void setPreferIpAddress(boolean preferIpAddress) {
+		this.preferIpAddress = preferIpAddress;
+	}
+
+	public boolean isPreferAgentAddress() {
+		return preferAgentAddress;
+	}
+
+	public void setPreferAgentAddress(boolean preferAgentAddress) {
+		this.preferAgentAddress = preferAgentAddress;
+	}
+
+	public int getCatalogServicesWatchDelay() {
+		return catalogServicesWatchDelay;
+	}
+
+	public void setCatalogServicesWatchDelay(int catalogServicesWatchDelay) {
+		this.catalogServicesWatchDelay = catalogServicesWatchDelay;
+	}
+
+	public int getCatalogServicesWatchTimeout() {
+		return catalogServicesWatchTimeout;
+	}
+
+	public void setCatalogServicesWatchTimeout(int catalogServicesWatchTimeout) {
+		this.catalogServicesWatchTimeout = catalogServicesWatchTimeout;
+	}
+
+	public String getServiceName() {
+		return serviceName;
+	}
+
+	public void setServiceName(String serviceName) {
+		this.serviceName = serviceName;
+	}
+
+	public String getInstanceId() {
+		return instanceId;
+	}
+
+	public void setInstanceId(String instanceId) {
+		this.instanceId = instanceId;
+	}
+
+	public String getInstanceZone() {
+		return instanceZone;
+	}
+
+	public void setInstanceZone(String instanceZone) {
+		this.instanceZone = instanceZone;
+	}
+
+	public String getInstanceGroup() {
+		return instanceGroup;
+	}
+
+	public void setInstanceGroup(String instanceGroup) {
+		this.instanceGroup = instanceGroup;
+	}
+
+	public String getDefaultZoneMetadataName() {
+		return defaultZoneMetadataName;
+	}
+
+	public void setDefaultZoneMetadataName(String defaultZoneMetadataName) {
+		this.defaultZoneMetadataName = defaultZoneMetadataName;
+	}
+
+	public String getScheme() {
+		return scheme;
+	}
+
+	public void setScheme(String scheme) {
+		this.scheme = scheme;
+	}
+
+	public String getManagementSuffix() {
+		return managementSuffix;
+	}
+
+	public void setManagementSuffix(String managementSuffix) {
+		this.managementSuffix = managementSuffix;
+	}
+
+	public Map<String, String> getServerListQueryTags() {
+		return serverListQueryTags;
+	}
+
+	public void setServerListQueryTags(Map<String, String> serverListQueryTags) {
+		this.serverListQueryTags = serverListQueryTags;
+	}
+
+	public Map<String, String> getDatacenters() {
+		return datacenters;
+	}
+
+	public void setDatacenters(Map<String, String> datacenters) {
+		this.datacenters = datacenters;
+	}
+
+	public String getDefaultQueryTag() {
+		return defaultQueryTag;
+	}
+
+	public void setDefaultQueryTag(String defaultQueryTag) {
+		this.defaultQueryTag = defaultQueryTag;
+	}
+
+	public boolean isQueryPassing() {
+		return queryPassing;
+	}
+
+	public void setQueryPassing(boolean queryPassing) {
+		this.queryPassing = queryPassing;
+	}
+
+	public boolean isRegister() {
+		return register;
+	}
+
+	public void setRegister(boolean register) {
+		this.register = register;
+	}
+
+	public boolean isDeregister() {
+		return deregister;
+	}
+
+	public void setDeregister(boolean deregister) {
+		this.deregister = deregister;
+	}
+
+	public boolean isRegisterHealthCheck() {
+		return registerHealthCheck;
+	}
+
+	public void setRegisterHealthCheck(boolean registerHealthCheck) {
+		this.registerHealthCheck = registerHealthCheck;
+	}
+
+	public boolean isFailFast() {
+		return failFast;
+	}
+
+	public void setFailFast(boolean failFast) {
+		this.failFast = failFast;
+	}
+
+	public Boolean getHealthCheckTlsSkipVerify() {
+		return healthCheckTlsSkipVerify;
+	}
+
+	public void setHealthCheckTlsSkipVerify(Boolean healthCheckTlsSkipVerify) {
+		this.healthCheckTlsSkipVerify = healthCheckTlsSkipVerify;
+	}
+
+	public String getTsfApplicationId() {
+		return tsfApplicationId;
+	}
+
+	public void setTsfApplicationId(final String tsfApplicationId) {
+		this.tsfApplicationId = tsfApplicationId;
+	}
+
+	public String getTsfGroupId() {
+		return tsfGroupId;
+	}
+
+	public void setTsfGroupId(final String tsfGroupId) {
+		this.tsfGroupId = tsfGroupId;
+	}
+
+	public String getTsfNamespaceId() {
+		return tsfNamespaceId;
+	}
+
+	public void setTsfNamespaceId(String tsfNamespaceId) {
+		this.tsfNamespaceId = tsfNamespaceId;
+	}
+
+	public String getTsfProgVersion() {
+		return tsfProgVersion;
+	}
+
+	public void setTsfProgVersion(final String tsfProgVersion) {
+		this.tsfProgVersion = tsfProgVersion;
+	}
+
+	public String getTsfRegion() {
+		return tsfRegion;
+	}
+
+	public void setTsfRegion(final String tsfRegion) {
+		this.tsfRegion = tsfRegion;
+	}
+
+	public String getTsfZone() {
+		return tsfZone;
+	}
+
+	public void setTsfZone(final String tsfZone) {
+		this.tsfZone = tsfZone;
+	}
+
+	public Map<String, String> getServiceMeta() {
+		return serviceMeta;
+	}
+
+	public void setServiceMeta(final Map<String, String> serviceMeta) {
+		this.serviceMeta = serviceMeta;
+	}
+
+	public int getCallbackPoolSize() {
+		return callbackPoolSize;
+	}
+
+	public void setCallbackPoolSize(int callbackPoolSize) {
+		this.callbackPoolSize = callbackPoolSize;
+	}
+
+	public long getCallbackInitialDelay() {
+		return callbackInitialDelay;
+	}
+
+	public void setCallbackInitialDelay(long callbackInitialDelay) {
+		this.callbackInitialDelay = callbackInitialDelay;
+	}
+
+	public long getCallbackErrorDelay() {
+		return callbackErrorDelay;
+	}
+
+	public void setCallbackErrorDelay(long callbackErrorDelay) {
+		this.callbackErrorDelay = callbackErrorDelay;
+	}
+
+	public boolean isZeroInstanceProtect() {
+		return zeroInstanceProtect;
+	}
+
+	public void setZeroInstanceProtect(boolean zeroInstanceProtect) {
+		this.zeroInstanceProtect = zeroInstanceProtect;
+	}
+
+	public int getTestConnectivityTimeout() {
+		return testConnectivityTimeout;
+	}
+
+	public void setTestConnectivityTimeout(int testConnectivityTimeout) {
+		this.testConnectivityTimeout = testConnectivityTimeout;
+	}
+
+	@Override
+	public String toString() {
+		return "ConsulDiscoveryProperties{" +
+				"hostInfo=" + hostInfo +
+				", aclToken='" + aclToken + '\'' +
+				", tags=" + tags +
+				", enabled=" + enabled +
+				", managementTags=" + managementTags +
+				", healthCheckPath='" + healthCheckPath + '\'' +
+				", healthCheckUrl='" + healthCheckUrl + '\'' +
+				", healthCheckInterval='" + healthCheckInterval + '\'' +
+				", healthCheckTimeout='" + healthCheckTimeout + '\'' +
+				", healthCheckCriticalTimeout='" + healthCheckCriticalTimeout + '\'' +
+				", ipAddress='" + ipAddress + '\'' +
+				", hostname='" + hostname + '\'' +
+				", port=" + port +
+				", managementPort=" + managementPort +
+				", lifecycle=" + lifecycle +
+				", preferIpAddress=" + preferIpAddress +
+				", preferAgentAddress=" + preferAgentAddress +
+				", catalogServicesWatchDelay=" + catalogServicesWatchDelay +
+				", catalogServicesWatchTimeout=" + catalogServicesWatchTimeout +
+				", serviceName='" + serviceName + '\'' +
+				", instanceId='" + instanceId + '\'' +
+				", instanceZone='" + instanceZone + '\'' +
+				", instanceGroup='" + instanceGroup + '\'' +
+				", defaultZoneMetadataName='" + defaultZoneMetadataName + '\'' +
+				", scheme='" + scheme + '\'' +
+				", managementSuffix='" + managementSuffix + '\'' +
+				", serverListQueryTags=" + serverListQueryTags +
+				", datacenters=" + datacenters +
+				", defaultQueryTag='" + defaultQueryTag + '\'' +
+				", queryPassing=" + queryPassing +
+				", register=" + register +
+				", deregister=" + deregister +
+				", registerHealthCheck=" + registerHealthCheck +
+				", failFast=" + failFast +
+				", healthCheckTlsSkipVerify=" + healthCheckTlsSkipVerify +
+				'}';
+	}
+
+	public static class Lifecycle {
+		private boolean enabled = true;
+
+		public boolean isEnabled() {
+			return enabled;
+		}
+
+		public void setEnabled(boolean enabled) {
+			this.enabled = enabled;
+		}
+
+		@Override
+		public String toString() {
+			return "Lifecycle{" +
+					"enabled=" + enabled +
+					'}';
+		}
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryPropertiesAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryPropertiesAutoConfiguration.java
new file mode 100644
index 000000000..e961b2e28
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryPropertiesAutoConfiguration.java
@@ -0,0 +1,83 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf;
+
+import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
+import com.tencent.cloud.common.util.inet.PolarisInetUtils;
+import com.tencent.cloud.plugin.lossless.config.LosslessProperties;
+import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
+import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
+import com.tencent.cloud.polaris.context.tsf.config.TsfCoreProperties;
+import com.tencent.cloud.polaris.context.tsf.consul.TsfConsulProperties;
+import com.tencent.cloud.polaris.tsf.lossless.TsfLosslessConfigModifier;
+import com.tencent.cloud.polaris.tsf.lossless.TsfLosslessProperties;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Auto configuration for TSF discovery.
+ *
+ * @author Haotian Zhang
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnTsfEnabled
+public class TsfDiscoveryPropertiesAutoConfiguration {
+
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfDiscoveryProperties tsfDiscoveryProperties(PolarisInetUtils polarisInetUtils) {
+		return new TsfDiscoveryProperties(polarisInetUtils);
+	}
+
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfHeartbeatProperties tsfHeartbeatProperties() {
+		return new TsfHeartbeatProperties();
+	}
+
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfLosslessProperties tsfLosslessProperties() {
+		return new TsfLosslessProperties();
+	}
+
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfDiscoveryConfigModifier tsfDiscoveryConfigModifier(TsfCoreProperties tsfCoreProperties,
+			TsfConsulProperties tsfConsulProperties, TsfDiscoveryProperties tsfDiscoveryProperties,
+			TsfHeartbeatProperties tsfHeartbeatProperties, PolarisDiscoveryProperties polarisDiscoveryProperties,
+			PolarisContextProperties polarisContextProperties, ApplicationContext context) {
+		return new TsfDiscoveryConfigModifier(tsfCoreProperties, tsfConsulProperties, tsfDiscoveryProperties,
+				tsfHeartbeatProperties, polarisDiscoveryProperties, polarisContextProperties, context);
+	}
+
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfZeroProtectionConfigModifier tsfZeroProtectionConfigModifier() {
+		return new TsfZeroProtectionConfigModifier();
+	}
+
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfLosslessConfigModifier tsfLosslessConfigModifier(LosslessProperties losslessProperties, TsfLosslessProperties tsfLosslessProperties) {
+		return new TsfLosslessConfigModifier(losslessProperties, tsfLosslessProperties);
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryPropertiesBootstrapConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryPropertiesBootstrapConfiguration.java
new file mode 100644
index 000000000..ad42d3b05
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfDiscoveryPropertiesBootstrapConfiguration.java
@@ -0,0 +1,38 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf;
+import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
+import com.tencent.cloud.polaris.DiscoveryPropertiesAutoConfiguration;
+
+import org.springframework.cloud.commons.util.UtilAutoConfiguration;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * Bootstrap configuration for TSF discovery.
+ *
+ * @author Haotian Zhang
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnTsfEnabled
+@Import({TsfDiscoveryPropertiesAutoConfiguration.class,
+		DiscoveryPropertiesAutoConfiguration.class,
+		UtilAutoConfiguration.class})
+public class TsfDiscoveryPropertiesBootstrapConfiguration {
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfHeartbeatProperties.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfHeartbeatProperties.java
new file mode 100644
index 000000000..e946c5cec
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfHeartbeatProperties.java
@@ -0,0 +1,110 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf;
+
+import javax.validation.constraints.DecimalMax;
+import javax.validation.constraints.DecimalMin;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+
+import org.apache.commons.logging.Log;
+import org.joda.time.Period;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.core.style.ToStringCreator;
+import org.springframework.validation.annotation.Validated;
+
+@ConfigurationProperties(prefix = "tsf.discovery.heartbeat")
+@Validated
+public class TsfHeartbeatProperties {
+
+	private static final Log log = org.apache.commons.logging.LogFactory.getLog(TsfHeartbeatProperties.class);
+	// TODO: change enabled to default to true when I stop seeing messages like
+	// [WARN] agent: Check 'service:testConsulApp:xtest:8080' missed TTL, is now critical
+	boolean enabled = true;
+
+	@Min(1)
+	private int ttlValue = 30;
+
+	@NotNull
+	private String ttlUnit = "s";
+
+	@DecimalMin("0.1")
+	@DecimalMax("0.9")
+	private double intervalRatio = 2.0 / 3.0;
+
+	//TODO: did heartbeatInterval need to be a field?
+
+	protected Period computeHearbeatInterval() {
+		// heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser
+		// priority), no sooner than 1s from now
+		double interval = ttlValue * intervalRatio;
+		double max = Math.max(interval, 1);
+		int ttlMinus1 = ttlValue - 1;
+		double min = Math.min(ttlMinus1, max);
+		Period heartbeatInterval = new Period(Math.round(1000 * min));
+		log.debug("Computed heartbeatInterval: " + heartbeatInterval);
+		return heartbeatInterval;
+	}
+
+	public String getTtl() {
+		return ttlValue + ttlUnit;
+	}
+
+	public boolean isEnabled() {
+		return this.enabled;
+	}
+
+	public void setEnabled(boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	public @Min(1) int getTtlValue() {
+		return this.ttlValue;
+	}
+
+	public void setTtlValue(@Min(1) int ttlValue) {
+		this.ttlValue = ttlValue;
+	}
+
+	public @NotNull String getTtlUnit() {
+		return this.ttlUnit;
+	}
+
+	public void setTtlUnit(@NotNull String ttlUnit) {
+		this.ttlUnit = ttlUnit;
+	}
+
+	public @DecimalMin("0.1") @DecimalMax("0.9") double getIntervalRatio() {
+		return this.intervalRatio;
+	}
+
+	public void setIntervalRatio(@DecimalMin("0.1") @DecimalMax("0.9") double intervalRatio) {
+		this.intervalRatio = intervalRatio;
+	}
+
+	@Override
+	public String toString() {
+		return new ToStringCreator(this)
+				.append("enabled", enabled)
+				.append("ttlValue", ttlValue)
+				.append("ttlUnit", ttlUnit)
+				.append("intervalRatio", intervalRatio)
+				.toString();
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfZeroProtectionConfigModifier.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfZeroProtectionConfigModifier.java
new file mode 100644
index 000000000..0a78d1a73
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/TsfZeroProtectionConfigModifier.java
@@ -0,0 +1,40 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf;
+
+import com.tencent.cloud.common.constant.OrderConstant;
+import com.tencent.cloud.polaris.context.PolarisConfigModifier;
+import com.tencent.polaris.factory.config.ConfigurationImpl;
+
+/**
+ * Modifier for TSF discovery zero protection.
+ *
+ * @author Haotian Zhang
+ */
+public class TsfZeroProtectionConfigModifier implements PolarisConfigModifier {
+	@Override
+	public void modify(ConfigurationImpl configuration) {
+		configuration.getConsumer().getZeroProtection().setEnable(true);
+		configuration.getConsumer().getZeroProtection().setNeedTestConnectivity(true);
+	}
+
+	@Override
+	public int getOrder() {
+		return OrderConstant.Modifier.DISCOVERY_ORDER + 1;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/consts/WarmupCons.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/consts/WarmupCons.java
new file mode 100644
index 000000000..53bce11c8
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/consts/WarmupCons.java
@@ -0,0 +1,38 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf.consts;
+
+/**
+ * 预热所需枚举.
+ * @author jiangfan
+ */
+public final class WarmupCons {
+
+	/**
+	 * 预热保护阈值.
+	 */
+	public static double DEFAULT_PROTECTION_THRESHOLD_KEY = 50;
+	/**
+	 * TSF 启动时间。预热开始时间.
+	 */
+	public static String TSF_START_TIME = "TSF_START_TIME";
+
+	private WarmupCons() {
+
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/lossless/TsfLosslessConfigModifier.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/lossless/TsfLosslessConfigModifier.java
new file mode 100644
index 000000000..40a6fda0e
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/lossless/TsfLosslessConfigModifier.java
@@ -0,0 +1,50 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf.lossless;
+
+import com.tencent.cloud.common.constant.OrderConstant;
+import com.tencent.cloud.plugin.lossless.config.LosslessProperties;
+import com.tencent.cloud.polaris.context.PolarisConfigModifier;
+import com.tencent.polaris.factory.config.ConfigurationImpl;
+
+/**
+ * Modifier for TSF lossless online offline.
+ *
+ * @author Haotian Zhang
+ */
+public class TsfLosslessConfigModifier implements PolarisConfigModifier {
+
+	private final LosslessProperties losslessProperties;
+	private final TsfLosslessProperties tsfLosslessProperties;
+
+	public TsfLosslessConfigModifier(LosslessProperties losslessProperties, TsfLosslessProperties tsfLosslessProperties) {
+		this.losslessProperties = losslessProperties;
+		this.tsfLosslessProperties = tsfLosslessProperties;
+	}
+
+	@Override
+	public void modify(ConfigurationImpl configuration) {
+		losslessProperties.setEnabled(true);
+		losslessProperties.setPort(tsfLosslessProperties.getPort());
+	}
+
+	@Override
+	public int getOrder() {
+		return OrderConstant.Modifier.LOSSLESS_ORDER - 1;
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/lossless/TsfLosslessProperties.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/lossless/TsfLosslessProperties.java
new file mode 100644
index 000000000..0be0d5977
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/lossless/TsfLosslessProperties.java
@@ -0,0 +1,48 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf.lossless;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * 优雅上下线的配置.
+ *
+ * @author Haotian Zhang
+ */
+@ConfigurationProperties("tsf.discovery.lossless")
+public class TsfLosslessProperties {
+
+	@Value("${tsf.discovery.lossless.port:${tsf_sctt_extensions_port:11134}}")
+	private int port = 11134;
+
+	public int getPort() {
+		return port;
+	}
+
+	public void setPort(int port) {
+		this.port = port;
+	}
+
+	@Override
+	public String toString() {
+		return "TsfLosslessProperties{" +
+				"port=" + port +
+				'}';
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfApiPolarisRegistrationCustomizer.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfApiPolarisRegistrationCustomizer.java
new file mode 100644
index 000000000..c193f06c3
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfApiPolarisRegistrationCustomizer.java
@@ -0,0 +1,62 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf.registry;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.tencent.cloud.polaris.registry.PolarisRegistration;
+import com.tencent.cloud.polaris.registry.PolarisRegistrationCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.util.StringUtils;
+
+import static com.tencent.polaris.api.config.plugin.DefaultPlugins.SERVER_CONNECTOR_CONSUL;
+
+/**
+ * Set API data to registration metadata.
+ *
+ * @author Haotian Zhang
+ */
+public class TsfApiPolarisRegistrationCustomizer implements PolarisRegistrationCustomizer {
+	private static final Logger LOG = LoggerFactory.getLogger(TsfApiPolarisRegistrationCustomizer.class);
+
+	private static final String API_META_KEY = "TSF_API_METAS";
+	private final ApplicationContext context;
+
+	public TsfApiPolarisRegistrationCustomizer(ApplicationContext context) {
+		this.context = context;
+	}
+
+	@Override
+	public void customize(PolarisRegistration registration) {
+		String apiMetaData = context.getEnvironment().getProperty("$api_metas");
+		Map<String, Map<String, String>> metadata = registration.getExtendedMetadata();
+		if (StringUtils.hasText(apiMetaData)) {
+			if (!metadata.containsKey(SERVER_CONNECTOR_CONSUL)) {
+				metadata.put(SERVER_CONNECTOR_CONSUL, new HashMap<>());
+			}
+			metadata.get(SERVER_CONNECTOR_CONSUL).put(API_META_KEY, apiMetaData);
+		}
+		else {
+			LOG.warn("apiMetaData is null, service:{}", registration.getServiceId());
+		}
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfDiscoveryRegistryAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfDiscoveryRegistryAutoConfiguration.java
new file mode 100644
index 000000000..39f8e3b44
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfDiscoveryRegistryAutoConfiguration.java
@@ -0,0 +1,75 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf.registry;
+import javax.servlet.ServletContext;
+
+import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
+import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
+import com.tencent.cloud.polaris.registry.PolarisServiceRegistryAutoConfiguration;
+import com.tencent.cloud.polaris.tsf.TsfDiscoveryProperties;
+import com.tencent.cloud.polaris.tsf.TsfHeartbeatProperties;
+
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Auto configuration for TSF discovery.
+ *
+ * @author Haotian Zhang
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnTsfEnabled
+@AutoConfigureBefore(PolarisServiceRegistryAutoConfiguration.class)
+public class TsfDiscoveryRegistryAutoConfiguration {
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfMetadataPolarisRegistrationCustomizer tsfMetadataPolarisRegistrationCustomizer(TsfDiscoveryProperties tsfDiscoveryProperties) {
+		return new TsfMetadataPolarisRegistrationCustomizer(tsfDiscoveryProperties);
+	}
+
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfPortPolarisRegistrationCustomizer tsfPortPolarisRegistrationCustomizer(
+			AutoServiceRegistrationProperties autoServiceRegistrationProperties,
+			ApplicationContext context, TsfDiscoveryProperties tsfDiscoveryProperties,
+			TsfHeartbeatProperties tsfHeartbeatProperties, PolarisSDKContextManager polarisSDKContextManager) {
+		return new TsfPortPolarisRegistrationCustomizer(autoServiceRegistrationProperties, context,
+				tsfDiscoveryProperties, tsfHeartbeatProperties, polarisSDKContextManager.getSDKContext());
+	}
+
+	@Bean
+	@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
+	@ConditionalOnMissingBean
+	public TsfServletRegistrationCustomizer tsfServletConsulCustomizer(ObjectProvider<ServletContext> servletContext) {
+		return new TsfServletRegistrationCustomizer(servletContext);
+	}
+
+	@Bean
+	@ConditionalOnMissingBean
+	@ConditionalOnProperty(value = "tsf.swagger.enabled", havingValue = "true", matchIfMissing = true)
+	public TsfApiPolarisRegistrationCustomizer tsfApiPolarisRegistrationCustomizer(ApplicationContext context) {
+		return new TsfApiPolarisRegistrationCustomizer(context);
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfMetadataPolarisRegistrationCustomizer.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfMetadataPolarisRegistrationCustomizer.java
new file mode 100644
index 000000000..9b698c59f
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfMetadataPolarisRegistrationCustomizer.java
@@ -0,0 +1,60 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf.registry;
+
+import java.util.Map;
+
+import com.tencent.cloud.common.constant.SdkVersion;
+import com.tencent.cloud.common.util.JacksonUtils;
+import com.tencent.cloud.polaris.registry.PolarisRegistration;
+import com.tencent.cloud.polaris.registry.PolarisRegistrationCustomizer;
+import com.tencent.cloud.polaris.tsf.TsfDiscoveryProperties;
+import com.tencent.cloud.polaris.tsf.consts.WarmupCons;
+import com.tencent.cloud.polaris.tsf.util.RegistrationUtil;
+
+/**
+ *
+ *
+ * @author Haotian Zhang
+ */
+public class TsfMetadataPolarisRegistrationCustomizer implements PolarisRegistrationCustomizer {
+
+	private final TsfDiscoveryProperties tsfDiscoveryProperties;
+
+	public TsfMetadataPolarisRegistrationCustomizer(TsfDiscoveryProperties tsfDiscoveryProperties) {
+		this.tsfDiscoveryProperties = tsfDiscoveryProperties;
+	}
+
+	@Override
+	public void customize(PolarisRegistration registration) {
+		Map<String, String> metadata = registration.getMetadata();
+
+		metadata.put("TSF_APPLICATION_ID", tsfDiscoveryProperties.getTsfApplicationId());
+		metadata.put("TSF_PROG_VERSION", tsfDiscoveryProperties.getTsfProgVersion());
+		metadata.put("TSF_GROUP_ID", tsfDiscoveryProperties.getTsfGroupId());
+		metadata.put("TSF_NAMESPACE_ID", tsfDiscoveryProperties.getTsfNamespaceId());
+		metadata.put("TSF_INSTNACE_ID", tsfDiscoveryProperties.getInstanceId());
+		metadata.put("TSF_REGION", tsfDiscoveryProperties.getTsfRegion());
+		metadata.put("TSF_ZONE", tsfDiscoveryProperties.getTsfZone());
+		// 处理预热相关的参数
+		metadata.put(WarmupCons.TSF_START_TIME, String.valueOf(System.currentTimeMillis()));
+		metadata.put("TSF_SDK_VERSION", SdkVersion.get());
+		metadata.put("TSF_TAGS", JacksonUtils.serialize2Json(RegistrationUtil.createTags(tsfDiscoveryProperties)));
+		RegistrationUtil.appendMetaIpAddress(metadata);
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfPortPolarisRegistrationCustomizer.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfPortPolarisRegistrationCustomizer.java
new file mode 100644
index 000000000..65372d5a1
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfPortPolarisRegistrationCustomizer.java
@@ -0,0 +1,62 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf.registry;
+
+import com.tencent.cloud.polaris.registry.PolarisRegistration;
+import com.tencent.cloud.polaris.registry.PolarisRegistrationCustomizer;
+import com.tencent.cloud.polaris.tsf.TsfDiscoveryProperties;
+import com.tencent.cloud.polaris.tsf.TsfHeartbeatProperties;
+import com.tencent.cloud.polaris.tsf.util.RegistrationUtil;
+import com.tencent.polaris.client.api.SDKContext;
+
+import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * 服务注册时端口相关逻辑.
+ *
+ * @author Haotian Zhang
+ */
+public class TsfPortPolarisRegistrationCustomizer implements PolarisRegistrationCustomizer {
+
+	private final AutoServiceRegistrationProperties autoServiceRegistrationProperties;
+	private final ApplicationContext context;
+	private final TsfDiscoveryProperties tsfDiscoveryProperties;
+	private final TsfHeartbeatProperties tsfHeartbeatProperties;
+	private final SDKContext sdkContext;
+
+	public TsfPortPolarisRegistrationCustomizer(AutoServiceRegistrationProperties autoServiceRegistrationProperties,
+			ApplicationContext context, TsfDiscoveryProperties tsfDiscoveryProperties,
+			TsfHeartbeatProperties tsfHeartbeatProperties, SDKContext sdkContext) {
+		this.autoServiceRegistrationProperties = autoServiceRegistrationProperties;
+		this.context = context;
+		this.tsfDiscoveryProperties = tsfDiscoveryProperties;
+		this.tsfHeartbeatProperties = tsfHeartbeatProperties;
+		this.sdkContext = sdkContext;
+	}
+
+	@Override
+	public void customize(PolarisRegistration registration) {
+		if (tsfDiscoveryProperties.getPort() != null) {
+			registration.setPort(tsfDiscoveryProperties.getPort());
+		}
+		// we know the port and can set the check
+		RegistrationUtil.setCheck(autoServiceRegistrationProperties, tsfDiscoveryProperties, context,
+				tsfHeartbeatProperties, registration, sdkContext.getConfig());
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfServletRegistrationCustomizer.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfServletRegistrationCustomizer.java
new file mode 100644
index 000000000..f4321b743
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/registry/TsfServletRegistrationCustomizer.java
@@ -0,0 +1,66 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf.registry;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+
+import com.tencent.cloud.common.util.JacksonUtils;
+import com.tencent.cloud.polaris.registry.PolarisRegistration;
+import com.tencent.cloud.polaris.registry.PolarisRegistrationCustomizer;
+import com.tencent.polaris.plugins.connector.common.constant.ConsulConstant;
+
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.util.StringUtils;
+
+import static com.tencent.polaris.plugins.connector.common.constant.ConsulConstant.MetadataMapKey.TAGS_KEY;
+
+/**
+ * @author Piotr Wielgolaski
+ */
+public class TsfServletRegistrationCustomizer implements PolarisRegistrationCustomizer {
+	private final ObjectProvider<ServletContext> servletContext;
+
+	public TsfServletRegistrationCustomizer(ObjectProvider<ServletContext> servletContext) {
+		this.servletContext = servletContext;
+	}
+
+	@Override
+	public void customize(PolarisRegistration registration) {
+		if (servletContext == null) {
+			return;
+		}
+		ServletContext sc = servletContext.getIfAvailable();
+		if (sc != null
+				&& StringUtils.hasText(sc.getContextPath())
+				&& StringUtils.hasText(sc.getContextPath().replaceAll("/", ""))) {
+			Map<String, String> metadata = registration.getMetadata();
+
+			List<String> tags = Arrays.asList(JacksonUtils.deserialize(metadata.get(TAGS_KEY), String[].class));
+			if (tags == null) {
+				tags = new ArrayList<>();
+			}
+			tags.add("contextPath=" + sc.getContextPath());
+			metadata.put(ConsulConstant.MetadataMapKey.TAGS_KEY, JacksonUtils.serialize2Json(tags));
+		}
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/util/RegistrationUtil.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/util/RegistrationUtil.java
new file mode 100644
index 000000000..bb95c8d83
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/tsf/util/RegistrationUtil.java
@@ -0,0 +1,231 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.tsf.util;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import com.ecwid.consul.v1.agent.model.NewService;
+import com.tencent.cloud.common.util.AddressUtils;
+import com.tencent.cloud.common.util.JacksonUtils;
+import com.tencent.cloud.common.util.inet.PolarisInetUtils;
+import com.tencent.cloud.polaris.tsf.TsfDiscoveryProperties;
+import com.tencent.cloud.polaris.tsf.TsfHeartbeatProperties;
+import com.tencent.polaris.api.config.Configuration;
+import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl;
+import com.tencent.polaris.plugins.connector.common.constant.ConsulConstant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.client.discovery.ManagementServerPortUtils;
+import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
+import org.springframework.cloud.client.serviceregistry.Registration;
+import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
+import org.springframework.cloud.commons.util.IdUtils;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.env.Environment;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * TSF registration utils.
+ *
+ * @author Haotian Zhang
+ */
+public final class RegistrationUtil {
+	/**
+	 * - 分隔符.
+	 */
+	public static final char SEPARATOR = '-';
+	/**
+	 * Server connector ID.
+	 */
+	public static final String ID = "consul";
+	private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationUtil.class);
+	/**
+	 * IPV4.
+	 */
+	public static String TSF_ADDRESS_IPV4 = "TSF_ADDRESS_IPV4";
+
+	/**
+	 * IPV6.
+	 */
+	public static String TSF_ADDRESS_IPV6 = "TSF_ADDRESS_IPV6";
+
+	private RegistrationUtil() {
+	}
+
+	public static String getAppName(TsfDiscoveryProperties properties, Environment env) {
+		String appName = properties.getServiceName();
+		if (!StringUtils.isEmpty(appName)) {
+			return appName;
+		}
+		return env.getProperty("spring.application.name", "application");
+	}
+
+	public static String getInstanceId(TsfDiscoveryProperties properties, ApplicationContext context) {
+		// tsf consul 不支持 dns,所以这里不需要 normalize,并且由于优雅下线,readiness probe 联动都是依赖 service id 的,normalize 后两边对不上,所以需要去掉 normalize
+		if (!StringUtils.hasText(properties.getInstanceId())) {
+			return IdUtils.getDefaultInstanceId(context.getEnvironment(), false);
+		}
+		else {
+			return properties.getInstanceId();
+		}
+	}
+
+	// 更新了判断逻辑,仅判断为空的场景
+	public static String normalizeForDns(String s) {
+		// if (s == null || !Character.isLetter(s.charAt(0))
+		// || !Character.isLetterOrDigit(s.charAt(s.length()-1))) {
+		// throw new IllegalArgumentException("Consul service ids must not be empty,
+		// must start with a letter, end with a letter or digit, and have as interior
+		// characters only letters, digits, and hyphen");
+		// }
+
+		// tsf not check consul service instance id start with letter and end with
+		// letter or digit
+		if (s == null) {
+			throw new IllegalArgumentException("Consul service ids must not be empty");
+		}
+
+		StringBuilder normalized = new StringBuilder();
+		Character prev = null;
+		for (char curr : s.toCharArray()) {
+			Character toAppend = null;
+			if (Character.isLetterOrDigit(curr)) {
+				toAppend = curr;
+			}
+			else if (prev == null || !(prev == SEPARATOR)) {
+				toAppend = SEPARATOR;
+			}
+			if (toAppend != null) {
+				normalized.append(toAppend);
+				prev = toAppend;
+			}
+		}
+
+		return normalized.toString();
+	}
+
+	public static List<String> createTags(TsfDiscoveryProperties properties) {
+		List<String> tags = new LinkedList<>(properties.getTags());
+
+		if (StringUtils.hasText(properties.getInstanceZone())) {
+			tags.add(properties.getDefaultZoneMetadataName() + "=" + properties.getInstanceZone());
+		}
+		if (StringUtils.hasText(properties.getInstanceGroup())) {
+			tags.add("group=" + properties.getInstanceGroup());
+		}
+
+		//store the secure flag in the tags so that clients will be able to figure out whether to use http or https automatically
+		tags.add("secure=" + properties.getScheme().equalsIgnoreCase("https"));
+
+		return tags;
+	}
+
+	public static Map<String, String> appendMetaIpAddress(Map<String, String> meta) {
+		if (meta == null) {
+			return null;
+		}
+		String ipv4Address = PolarisInetUtils.getIpString(false);
+		if (ipv4Address != null) {
+			meta.put(TSF_ADDRESS_IPV4, ipv4Address);
+		}
+
+		String ipv6Address = PolarisInetUtils.getIpString(true);
+		if (ipv6Address != null) {
+			meta.put(TSF_ADDRESS_IPV6, ipv6Address);
+		}
+		return meta;
+	}
+
+	public static void setCheck(AutoServiceRegistrationProperties autoServiceRegistrationProperties,
+			TsfDiscoveryProperties properties, ApplicationContext context,
+			TsfHeartbeatProperties tsfHeartbeatProperties, Registration registration, Configuration configuration) {
+		if (properties.isRegisterHealthCheck()) {
+			Integer checkPort;
+			if (shouldRegisterManagement(autoServiceRegistrationProperties, properties, context)) {
+				checkPort = getManagementPort(properties, context);
+			}
+			else {
+				checkPort = registration.getPort();
+			}
+			Assert.notNull(checkPort, "checkPort may not be null");
+
+			for (ServerConnectorConfigImpl config : configuration.getGlobal().getServerConnectors()) {
+				if (org.apache.commons.lang.StringUtils.equals(config.getId(), ID)) {
+					Map<String, String> metadata = config.getMetadata();
+					NewService.Check check = createCheck(checkPort, tsfHeartbeatProperties, properties);
+					String checkJson = JacksonUtils.serialize2Json(check);
+					LOGGER.debug("Check is : {}", checkJson);
+					metadata.put(ConsulConstant.MetadataMapKey.CHECK_KEY, checkJson);
+				}
+			}
+
+		}
+	}
+
+	public static NewService.Check createCheck(Integer port, TsfHeartbeatProperties ttlConfig,
+			TsfDiscoveryProperties properties) {
+		NewService.Check check = new NewService.Check();
+		if (ttlConfig.isEnabled()) {
+			check.setTtl(ttlConfig.getTtl());
+			return check;
+		}
+
+		Assert.notNull(port, "createCheck port must not be null");
+		Assert.isTrue(port > 0, "createCheck port must be greater than 0");
+
+		if (properties.getHealthCheckUrl() != null) {
+			check.setHttp(properties.getHealthCheckUrl());
+		}
+		else {
+			check.setHttp(String.format("%s://%s:%s%s", properties.getScheme(),
+					AddressUtils.getIpCompatible(properties.getHostname()), port,
+					properties.getHealthCheckPath()));
+		}
+		check.setInterval(properties.getHealthCheckInterval());
+		check.setTimeout(properties.getHealthCheckTimeout());
+		if (StringUtils.hasText(properties.getHealthCheckCriticalTimeout())) {
+			check.setDeregisterCriticalServiceAfter(properties.getHealthCheckCriticalTimeout());
+		}
+		check.setTlsSkipVerify(properties.getHealthCheckTlsSkipVerify());
+		return check;
+	}
+
+	/**
+	 * @return if the management service should be registered with the {@link ServiceRegistry}
+	 */
+	public static boolean shouldRegisterManagement(AutoServiceRegistrationProperties autoServiceRegistrationProperties, TsfDiscoveryProperties properties, ApplicationContext context) {
+		return autoServiceRegistrationProperties.isRegisterManagement()
+				&& getManagementPort(properties, context) != null
+				&& ManagementServerPortUtils.isDifferent(context);
+	}
+
+	/**
+	 * @return the port of the Management Service
+	 */
+	public static Integer getManagementPort(TsfDiscoveryProperties properties, ApplicationContext context) {
+		// If an alternate external port is specified, use it instead
+		if (properties.getManagementPort() != null) {
+			return properties.getManagementPort();
+		}
+		return ManagementServerPortUtils.getPort(context);
+	}
+}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories
index 2a404639c..8b0e96f63 100644
--- a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/spring.factories
@@ -3,6 +3,9 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
   com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration,\
   com.tencent.cloud.polaris.registry.PolarisServiceRegistryAutoConfiguration,\
   com.tencent.cloud.polaris.endpoint.PolarisDiscoveryEndpointAutoConfiguration,\
-  com.tencent.cloud.polaris.loadbalancer.PolarisLoadBalancerAutoConfiguration
+  com.tencent.cloud.polaris.loadbalancer.PolarisLoadBalancerAutoConfiguration,\
+  com.tencent.cloud.polaris.tsf.TsfDiscoveryPropertiesAutoConfiguration,\
+  com.tencent.cloud.polaris.tsf.registry.TsfDiscoveryRegistryAutoConfiguration
 org.springframework.cloud.bootstrap.BootstrapConfiguration=\
-  com.tencent.cloud.polaris.DiscoveryPropertiesBootstrapAutoConfiguration
+  com.tencent.cloud.polaris.DiscoveryPropertiesBootstrapAutoConfiguration,\
+  com.tencent.cloud.polaris.tsf.TsfDiscoveryPropertiesBootstrapConfiguration
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspectTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspectTest.java
similarity index 97%
rename from spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspectTest.java
rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspectTest.java
index 45f656529..ba05d6619 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspectTest.java
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspectTest.java
@@ -73,6 +73,7 @@ public class LosslessRegistryAspectTest {
 					PolarisDiscoveryClientConfiguration.class,
 					PolarisDiscoveryAutoConfiguration.class))
 			.withPropertyValues("spring.cloud.nacos.discovery.enabled=false")
+			.withPropertyValues("spring.cloud.polaris.lossless.enabled=true")
 			.withPropertyValues("spring.cloud.polaris.lossless.delayRegisterInterval=5000")
 			.withPropertyValues("spring.cloud.polaris.lossless.healthCheckPath=")
 			.withPropertyValues("spring.cloud.polaris.lossless.port=" + LOSSLESS_PORT_1)
@@ -93,6 +94,7 @@ public class LosslessRegistryAspectTest {
 					PolarisDiscoveryClientConfiguration.class,
 					PolarisDiscoveryAutoConfiguration.class))
 			.withPropertyValues("spring.cloud.nacos.discovery.enabled=false")
+			.withPropertyValues("spring.cloud.polaris.lossless.enabled=true")
 			.withPropertyValues("spring.cloud.polaris.lossless.healthCheckInterval=1000")
 			.withPropertyValues("spring.cloud.polaris.lossless.healthCheckPath=/test")
 			.withPropertyValues("spring.cloud.polaris.lossless.port=28082")
@@ -138,8 +140,8 @@ public class LosslessRegistryAspectTest {
 			assertThatCode(() -> {
 				assertThat(OkHttpUtil.checkUrl(HOST, LOSSLESS_PORT_1, "/online", Collections.EMPTY_MAP)).isFalse();
 			}).doesNotThrowAnyException();
-			// delay register after 5s
-			Thread.sleep(5000);
+			// delay register after 10s
+			Thread.sleep(10000);
 			PolarisServiceRegistry registry = context.getBean(PolarisServiceRegistry.class);
 			PolarisRegistration registration = context.getBean(PolarisRegistration.class);
 
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessConfigModifierTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/plugin/lossless/config/LosslessConfigModifierTest.java
similarity index 96%
rename from spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessConfigModifierTest.java
rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/plugin/lossless/config/LosslessConfigModifierTest.java
index 0b0d847ff..9152f04f2 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessConfigModifierTest.java
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/plugin/lossless/config/LosslessConfigModifierTest.java
@@ -15,9 +15,8 @@
  * specific language governing permissions and limitations under the License.
  */
 
-package com.tencent.cloud.plugin.lossless;
+package com.tencent.cloud.plugin.lossless.config;
 
-import com.tencent.cloud.plugin.lossless.config.LosslessConfigModifier;
 import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
 import com.tencent.polaris.api.config.provider.LosslessConfig;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationUtils.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationUtils.java
similarity index 100%
rename from spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationUtils.java
rename to spring-cloud-starter-tencent-polaris-discovery/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationUtils.java
diff --git a/spring-cloud-tencent-commons/pom.xml b/spring-cloud-tencent-commons/pom.xml
index 8632ccdd3..a667b9831 100644
--- a/spring-cloud-tencent-commons/pom.xml
+++ b/spring-cloud-tencent-commons/pom.xml
@@ -50,6 +50,11 @@
 			<artifactId>spring-boot-starter-json</artifactId>
 		</dependency>
 
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-validation</artifactId>
+		</dependency>
+
 		<dependency>
 			<groupId>org.springframework.cloud</groupId>
 			<artifactId>spring-cloud-starter</artifactId>
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/ConditionalOnTsfEnabled.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/ConditionalOnTsfEnabled.java
new file mode 100644
index 000000000..dee92deb0
--- /dev/null
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/ConditionalOnTsfEnabled.java
@@ -0,0 +1,50 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.common.tsf;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.tencent.polaris.api.utils.StringUtils;
+
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+/**
+ * Condition that if Polaris enabled.
+ *
+ * @author Haotian Zhang
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Conditional(ConditionalOnTsfEnabled.OnTsfEnabledCondition.class)
+public @interface ConditionalOnTsfEnabled {
+
+	class OnTsfEnabledCondition implements Condition {
+
+		@Override
+		public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
+			String tsfAppId = conditionContext.getEnvironment().getProperty("tsf_app_id", "");
+			return StringUtils.isNotBlank(tsfAppId);
+		}
+	}
+}
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java
index 277a842db..3415cb799 100644
--- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/AddressUtils.java
@@ -19,18 +19,21 @@
 package com.tencent.cloud.common.util;
 
 import java.io.IOException;
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
 import java.net.Socket;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Enumeration;
 import java.util.List;
 
+import com.tencent.polaris.api.utils.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.springframework.util.StringUtils;
 
 /**
  * the utils of parse address.
@@ -43,11 +46,17 @@ public final class AddressUtils {
 
 	private static final String ADDRESS_SEPARATOR = ",";
 
+	private final static Boolean hasIpv6Address;
+
+	static {
+		hasIpv6Address = hasIpv6Address();
+	}
+
 	private AddressUtils() {
 	}
 
 	public static List<String> parseAddressList(String addressInfo) {
-		if (!StringUtils.hasText(addressInfo)) {
+		if (StringUtils.isBlank(addressInfo)) {
 			return Collections.emptyList();
 		}
 		List<String> addressList = new ArrayList<>();
@@ -77,4 +86,73 @@ public final class AddressUtils {
 		}
 		return true;
 	}
+
+	public static String getIpCompatible(String ip) {
+		if (StringUtils.isEmpty(ip)) {
+			return ip;
+		}
+		if (ip.contains(":") && !ip.startsWith("[") && !ip.endsWith("]")) {
+			return "[" + ip + "]";
+		}
+		return ip;
+	}
+
+	public static boolean preferIpv6() {
+		if (Boolean.FALSE.equals(hasIpv6Address)) {
+			LOGGER.debug("AddressUtils.preferIpv6 hasIpv6Address = false");
+			return false;
+		}
+		if ("true".equalsIgnoreCase(System.getenv("tsf_prefer_ipv6"))) {
+			LOGGER.debug("AddressUtils.preferIpv6 System.getenv = true");
+			return true;
+		}
+		if ("true".equalsIgnoreCase(System.getProperty("tsf_prefer_ipv6"))) {
+			LOGGER.debug("AddressUtils.preferIpv6 System.getProperty = true");
+			return true;
+		}
+		if ("true".equalsIgnoreCase(BeanFactoryUtils.resolve("${tsf_prefer_ipv6}"))) {
+			LOGGER.debug("AddressUtils.preferIpv6 BeanFactoryUtils.resolve = true");
+			return true;
+		}
+		LOGGER.debug("AddressUtils.preferIpv6 result = false");
+		return false;
+	}
+
+	/**
+	 * Determine whether environment has an ipv6 address.
+	 */
+	private static boolean hasIpv6Address() {
+		InetAddress result = null;
+		try {
+			int lowest = Integer.MAX_VALUE;
+			for (Enumeration<NetworkInterface> nics = NetworkInterface
+					.getNetworkInterfaces(); nics.hasMoreElements(); ) {
+				NetworkInterface ifc = nics.nextElement();
+				if (ifc.isUp()) {
+					LOGGER.trace("Testing interface: " + ifc.getDisplayName());
+					if (ifc.getIndex() < lowest || result == null) {
+						lowest = ifc.getIndex();
+					}
+					else if (result != null) {
+						continue;
+					}
+
+					for (Enumeration<InetAddress> addrs = ifc
+							.getInetAddresses(); addrs.hasMoreElements(); ) {
+						InetAddress address = addrs.nextElement();
+						if (address instanceof Inet6Address
+								&& !address.isLinkLocalAddress()
+								&& !address.isLoopbackAddress()) {
+							LOGGER.trace("Found non-loopback interface: " + ifc.getDisplayName());
+							return true;
+						}
+					}
+				}
+			}
+		}
+		catch (IOException ex) {
+			LOGGER.error("Cannot get first non-loopback address", ex);
+		}
+		return false;
+	}
 }
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java
index e7729cf18..cd982c680 100644
--- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/BeanFactoryUtils.java
@@ -13,7 +13,6 @@
  * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
- *
  */
 
 package com.tencent.cloud.common.util;
@@ -22,8 +21,15 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
 import org.springframework.beans.factory.ListableBeanFactory;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.stereotype.Component;
 
 import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors;
 
@@ -31,9 +37,30 @@ import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncl
  * the utils for bean factory.
  * @author lepdou 2022-05-23
  */
-public final class BeanFactoryUtils {
+@Component
+public final class BeanFactoryUtils implements BeanFactoryAware {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(BeanFactoryUtils.class);
 
-	private BeanFactoryUtils() {
+	private static BeanFactory beanFactory;
+
+	/**
+	 * Dynamic parsing of spring @Value.
+	 *
+	 * @param value something like ${}
+	 * @return return null if the parsing fails or the object is not found.
+	 */
+	public static String resolve(String value) {
+		try {
+			if (beanFactory instanceof ConfigurableBeanFactory) {
+				return ((ConfigurableBeanFactory) beanFactory).resolveEmbeddedValue(value);
+			}
+		}
+		catch (Exception e) {
+			LOGGER.error("resolve {} failed.", value, e);
+		}
+
+		return null;
 	}
 
 	public static <T> List<T> getBeans(BeanFactory beanFactory, Class<T> requiredType) {
@@ -45,4 +72,9 @@ public final class BeanFactoryUtils {
 		Map<String, T> beanMap = beansOfTypeIncludingAncestors((ListableBeanFactory) beanFactory, requiredType);
 		return new ArrayList<>(beanMap.values());
 	}
+
+	@Override
+	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+		BeanFactoryUtils.beanFactory = beanFactory;
+	}
 }
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/inet/PolarisInetUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/inet/PolarisInetUtils.java
new file mode 100644
index 000000000..e0afb55b6
--- /dev/null
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/inet/PolarisInetUtils.java
@@ -0,0 +1,320 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.common.util.inet;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import com.tencent.cloud.common.util.AddressUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.commons.util.InetUtils;
+import org.springframework.cloud.commons.util.InetUtilsProperties;
+
+
+/**
+ * Extend from {@link InetUtils}.
+ *
+ * @author Haotian Zhang
+ */
+public class PolarisInetUtils implements Closeable {
+
+	private static final Logger logger = LoggerFactory.getLogger(PolarisInetUtils.class);
+	// TODO: maybe shutdown the thread pool if it isn't being used?
+	private final ExecutorService executorService;
+	private final InetUtilsProperties properties;
+
+	public PolarisInetUtils(final InetUtilsProperties properties) {
+		this.properties = properties;
+		this.executorService = Executors
+				.newSingleThreadExecutor(r -> {
+					Thread thread = new Thread(r);
+					thread.setName(InetUtilsProperties.PREFIX);
+					thread.setDaemon(true);
+					return thread;
+				});
+	}
+
+	public static String getIpString(boolean _ipv6) {
+		InetAddress result = null;
+		try {
+			int lowest = Integer.MAX_VALUE;
+			for (Enumeration<NetworkInterface> nics = NetworkInterface
+					.getNetworkInterfaces(); nics.hasMoreElements(); ) {
+				NetworkInterface ifc = nics.nextElement();
+				if (ifc.isUp()) {
+					logger.trace("Testing interface: " + ifc.getDisplayName());
+					if (ifc.getIndex() < lowest || result == null) {
+						lowest = ifc.getIndex();
+					}
+					else if (result != null) {
+						continue;
+					}
+					for (Enumeration<InetAddress> addrs = ifc
+							.getInetAddresses(); addrs.hasMoreElements(); ) {
+						InetAddress address = addrs.nextElement();
+						if (_ipv6) {
+							if (address instanceof Inet6Address
+									&& !address.isLinkLocalAddress()
+									&& !address.isLoopbackAddress()
+							) {
+								logger.trace("Found non-loopback interface: "
+										+ ifc.getDisplayName());
+								result = address;
+							}
+						}
+						else {
+							if (address instanceof Inet4Address
+									&& !address.isLoopbackAddress()
+							) {
+								logger.trace("Found non-loopback interface: "
+										+ ifc.getDisplayName());
+								result = address;
+							}
+						}
+					}
+				}
+			}
+		}
+		catch (IOException ex) {
+			logger.error("Cannot get first non-loopback address", ex);
+		}
+
+		if (result == null) {
+			return null;
+		}
+
+		if (result.getHostAddress().contains("%")) {
+			return result.getHostAddress().split("%")[0];
+		}
+		else {
+			return result.getHostAddress();
+		}
+	}
+
+	@Override
+	public void close() {
+		executorService.shutdown();
+	}
+
+	public InetUtils.HostInfo findFirstNonLoopbackHostInfo() {
+		InetAddress address = findFirstNonLoopbackAddress();
+		if (address != null) {
+			return convertAddress(address);
+		}
+		InetUtils.HostInfo hostInfo = new InetUtils.HostInfo();
+		hostInfo.setHostname(this.properties.getDefaultHostname());
+		hostInfo.setIpAddress(this.properties.getDefaultIpAddress());
+		return hostInfo;
+	}
+
+	public InetAddress findFirstNonLoopbackAddress() {
+		boolean preferIpv6 = AddressUtils.preferIpv6();
+		InetAddress result = findFirstNonLoopbackAddressByIpType(preferIpv6);
+		logger.debug("ipv6 before, preferIpv6:{}, result:{}", preferIpv6, result);
+		if (result == null) {
+			result = findFirstNonLoopbackAddressByIpType(!preferIpv6);
+		}
+		logger.debug("ipv6 after, preferIpv6:{}, result:{}", preferIpv6, result);
+
+		if (result != null) {
+			return result;
+		}
+
+		try {
+			return InetAddress.getLocalHost();
+		}
+		catch (UnknownHostException e) {
+			logger.warn("Unable to retrieve localhost");
+		}
+
+		return null;
+	}
+
+	/** for testing. */
+	boolean isPreferredAddress(InetAddress address) {
+
+		if (this.properties.isUseOnlySiteLocalInterfaces()) {
+			final boolean siteLocalAddress = address.isSiteLocalAddress();
+			if (!siteLocalAddress) {
+				logger.trace("Ignoring address: " + address.getHostAddress());
+			}
+			return siteLocalAddress;
+		}
+		final List<String> preferredNetworks = this.properties.getPreferredNetworks();
+		if (preferredNetworks.isEmpty()) {
+			return true;
+		}
+		for (String regex : preferredNetworks) {
+			final String hostAddress = address.getHostAddress();
+			if (hostAddress.matches(regex) || hostAddress.startsWith(regex)) {
+				return true;
+			}
+		}
+		logger.trace("Ignoring address: " + address.getHostAddress());
+		return false;
+	}
+
+	/** for testing. */
+	boolean ignoreInterface(String interfaceName) {
+		for (String regex : this.properties.getIgnoredInterfaces()) {
+			if (interfaceName.matches(regex)) {
+				logger.trace("Ignoring interface: " + interfaceName);
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public InetUtils.HostInfo convertAddress(final InetAddress address) {
+		InetUtils.HostInfo hostInfo = new InetUtils.HostInfo();
+		Future<String> result = executorService.submit(new Callable<String>() {
+			@Override
+			public String call() throws Exception {
+				return address.getHostName();
+			}
+		});
+
+		String hostname;
+		try {
+			hostname = result.get(this.properties.getTimeoutSeconds(), TimeUnit.SECONDS);
+		}
+		catch (Exception e) {
+			logger.info("Cannot determine local hostname");
+			hostname = "localhost";
+		}
+		if (hostname.contains("%")) {
+			hostInfo.setHostname(hostname.split("%")[0]);
+		}
+		else {
+			hostInfo.setHostname(hostname);
+		}
+		if (address.getHostAddress().contains("%")) {
+			hostInfo.setIpAddress(address.getHostAddress().split("%")[0]);
+		}
+		else {
+			hostInfo.setIpAddress(address.getHostAddress());
+		}
+		return hostInfo;
+	}
+
+	public String findIpInterface() {
+		InetAddress address = findFirstNonLoopbackAddress();
+		if (address.getHostAddress().contains("%")) {
+			return address.getHostAddress().split("%")[1];
+		}
+		return "";
+	}
+
+	public String findIpAddress() {
+		InetAddress address = findFirstNonLoopbackAddress();
+		return address.getHostAddress().split("%")[0];
+	}
+
+	/**
+	 *
+	 * @return  "[ipv6]"
+	 */
+	public String findIpAddressWithBracket() {
+		InetAddress address = findFirstNonLoopbackAddress();
+		if (address.getHostAddress().contains("%")) {
+			return address.getHostAddress().split("%")[0];
+		}
+		return address.getHostAddress();
+	}
+
+	/**
+	 * @return ipv6%eth0
+	 *
+	 */
+	public String findIpAddressAndInterface() {
+		InetAddress address = findFirstNonLoopbackAddress();
+		return address.getHostAddress();
+	}
+
+	public InetAddress findFirstNonLoopbackAddressByIpType(boolean _ipv6) {
+		InetAddress result = null;
+		try {
+			int lowest = Integer.MAX_VALUE;
+			for (Enumeration<NetworkInterface> nics = NetworkInterface
+					.getNetworkInterfaces(); nics.hasMoreElements(); ) {
+				NetworkInterface ifc = nics.nextElement();
+				if (ifc.isUp()) {
+					logger.trace("Testing interface: " + ifc.getDisplayName());
+					if (ifc.getIndex() < lowest || result == null) {
+						lowest = ifc.getIndex();
+					}
+					else if (result != null) {
+						continue;
+					}
+
+					// @formatter:off
+					if (!ignoreInterface(ifc.getDisplayName())) {
+						for (Enumeration<InetAddress> addrs = ifc
+								.getInetAddresses(); addrs.hasMoreElements();) {
+							InetAddress address = addrs.nextElement();
+							if (_ipv6) {
+								if (address instanceof Inet6Address
+										&& !address.isLinkLocalAddress()
+										&& !address.isLoopbackAddress()
+										&& isPreferredAddress(address)) {
+									logger.trace("Found non-loopback interface: "
+											+ ifc.getDisplayName());
+									result = address;
+								}
+							}
+							else {
+								if (address instanceof Inet4Address
+										&& !address.isLoopbackAddress()
+										&& isPreferredAddress(address)) {
+									logger.trace("Found non-loopback interface: "
+											+ ifc.getDisplayName());
+									result = address;
+								}
+							}
+						}
+					}
+					// @formatter:on
+				}
+			}
+		}
+		catch (IOException ex) {
+			logger.error("Cannot get first non-loopback address", ex);
+		}
+
+		if (result != null) {
+			return result;
+		}
+
+
+		return null;
+	}
+}
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/inet/PolarisInetUtilsAutoConfiguration.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/inet/PolarisInetUtilsAutoConfiguration.java
new file mode 100644
index 000000000..b3b4655dc
--- /dev/null
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/inet/PolarisInetUtilsAutoConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.common.util.inet;
+
+import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.cloud.commons.util.InetUtilsProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+/**
+ * Auto configuration for PolarisInetUtils.
+ *
+ * @author Haotian Zhang
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnTsfEnabled
+public class PolarisInetUtilsAutoConfiguration {
+
+	@Bean
+	@ConditionalOnMissingBean
+	public PolarisInetUtils polarisInetUtils(InetUtilsProperties properties) {
+		return new PolarisInetUtils(properties);
+	}
+}
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/inet/PolarisInetUtilsBootstrapConfiguration.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/inet/PolarisInetUtilsBootstrapConfiguration.java
new file mode 100644
index 000000000..9973573d9
--- /dev/null
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/inet/PolarisInetUtilsBootstrapConfiguration.java
@@ -0,0 +1,30 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.common.util.inet;
+
+import org.springframework.context.annotation.Import;
+
+/**
+ * Auto configuration for PolarisInetUtils.
+ *
+ * @author Haotian Zhang
+ */
+@Import(PolarisInetUtilsAutoConfiguration.class)
+public class PolarisInetUtilsBootstrapConfiguration {
+
+}
diff --git a/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories
index 4c54d3372..d99cbf89a 100644
--- a/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-tencent-commons/src/main/resources/META-INF/spring.factories
@@ -1,4 +1,7 @@
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  com.tencent.cloud.common.util.inet.PolarisInetUtilsAutoConfiguration,\
   com.tencent.cloud.common.util.ApplicationContextAwareUtils,\
   com.tencent.cloud.common.metadata.config.MetadataAutoConfiguration,\
   com.tencent.cloud.common.metadata.endpoint.PolarisMetadataEndpointAutoConfiguration
+org.springframework.cloud.bootstrap.BootstrapConfiguration=\
+  com.tencent.cloud.common.util.inet.PolarisInetUtilsBootstrapConfiguration
diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml
index ddbf5cfcd..f2e7bc65c 100644
--- a/spring-cloud-tencent-dependencies/pom.xml
+++ b/spring-cloud-tencent-dependencies/pom.xml
@@ -74,7 +74,7 @@
 		<revision>1.14.0-2020.0.6-SNAPSHOT</revision>
 
 		<!-- Polaris SDK version -->
-		<polaris.version>1.15.6</polaris.version>
+		<polaris.version>1.15.7-SNAPSHOT</polaris.version>
 
 		<!-- Dependencies -->
 		<guava.version>32.0.1-jre</guava.version>
@@ -85,6 +85,7 @@
 		<byte-buddy.version>1.12.10</byte-buddy.version>
 		<jackson.version>2.12.7</jackson.version>
 		<protobuf-java.version>3.21.7</protobuf-java.version>
+		<joda-time.version>2.9.9</joda-time.version>
 		<system-stubs-jupiter.version>2.0.2</system-stubs-jupiter.version>
 
 		<!-- Maven Plugin Versions -->
@@ -259,6 +260,13 @@
 				<version>${byte-buddy.version}</version>
 			</dependency>
 
+
+			<dependency>
+				<groupId>joda-time</groupId>
+				<artifactId>joda-time</artifactId>
+				<version>${joda-time.version}</version>
+			</dependency>
+
 			<dependency>
 				<groupId>org.mockito</groupId>
 				<artifactId>mockito-inline</artifactId>
diff --git a/spring-cloud-tencent-examples/pom.xml b/spring-cloud-tencent-examples/pom.xml
index df75f878b..8eccfd444 100644
--- a/spring-cloud-tencent-examples/pom.xml
+++ b/spring-cloud-tencent-examples/pom.xml
@@ -23,6 +23,7 @@
 		<module>quickstart-example</module>
 		<module>lossless-example</module>
 		<module>polaris-router-grayrelease-lane-example</module>
+		<module>tsf-example</module>
 	</modules>
 
 	<properties>
diff --git a/spring-cloud-tencent-examples/tsf-example/consumer-demo/pom.xml b/spring-cloud-tencent-examples/tsf-example/consumer-demo/pom.xml
new file mode 100644
index 000000000..ca0dc4358
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/consumer-demo/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		 xmlns="http://maven.apache.org/POM/4.0.0"
+		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>tsf-example</artifactId>
+		<groupId>com.tencent.cloud</groupId>
+		<version>${revision}</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<artifactId>consumer-demo</artifactId>
+
+	<dependencies>
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-all</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-openfeign</artifactId>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+				<executions>
+					<execution>
+						<goals>
+							<goal>repackage</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<version>3.2.0</version>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+</project>
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/ConsumerApplication.java b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/ConsumerApplication.java
new file mode 100644
index 000000000..a28993aab
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/ConsumerApplication.java
@@ -0,0 +1,41 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.consumer;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Bean;
+import org.springframework.tsf.annotation.EnableTsf;
+import org.springframework.web.client.RestTemplate;
+
+@SpringBootApplication
+@EnableFeignClients // 使用Feign微服务调用时请启用
+@EnableTsf
+public class ConsumerApplication {
+	public static void main(String[] args) {
+		SpringApplication.run(ConsumerApplication.class, args);
+	}
+
+	@LoadBalanced
+	@Bean
+	public RestTemplate restTemplate() {
+		return new RestTemplate();
+	}
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/controller/ConsumerController.java b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/controller/ConsumerController.java
new file mode 100644
index 000000000..63f4f97f0
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/controller/ConsumerController.java
@@ -0,0 +1,53 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.consumer.controller;
+
+import com.tencent.cloud.tsf.demo.consumer.proxy.ProviderDemoService;
+import com.tencent.cloud.tsf.demo.consumer.proxy.ProviderService;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+
+@RestController
+public class ConsumerController {
+	@Autowired
+	private RestTemplate restTemplate;
+	@Autowired
+	private ProviderService providerService;
+	@Autowired
+	private ProviderDemoService providerDemoService;
+
+	@RequestMapping(value = "/echo-rest/{str}", method = RequestMethod.GET)
+	public String restProvider(@PathVariable String str) {
+		return restTemplate.getForObject("http://provider-demo/echo/" + str, String.class);
+	}
+
+	@RequestMapping(value = "/echo-feign/{str}", method = RequestMethod.GET)
+	public String feignProvider(@PathVariable String str) {
+		return providerDemoService.echo(str);
+	}
+
+	@RequestMapping(value = "/echo-feign-url/{str}", method = RequestMethod.GET)
+	public String feignUrlProvider(@PathVariable String str) {
+		return providerService.echo(str);
+	}
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/entity/CustomMetadata.java b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/entity/CustomMetadata.java
new file mode 100644
index 000000000..47a38b475
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/entity/CustomMetadata.java
@@ -0,0 +1,32 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.consumer.entity;
+
+/**
+ * 用户自定义 Metadata.
+ */
+public class CustomMetadata {
+
+	private String name;
+	private String value;
+
+	public CustomMetadata(String name, String value) {
+		this.name = name;
+		this.value = value;
+	}
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/proxy/ProviderDemoService.java b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/proxy/ProviderDemoService.java
new file mode 100644
index 000000000..c102fc84e
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/proxy/ProviderDemoService.java
@@ -0,0 +1,36 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.consumer.proxy;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient(name = "provider-demo")
+public interface ProviderDemoService {
+	@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
+	String echo(@PathVariable("str") String str);
+
+	@RequestMapping(value = "/echo/error/{str}", method = RequestMethod.GET)
+	String echoError(@PathVariable("str") String str);
+
+	@RequestMapping(value = "/echo/slow/{str}", method = RequestMethod.GET)
+	String echoSlow(@PathVariable("str") String str, @RequestParam("delay") int delay);
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/proxy/ProviderService.java b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/proxy/ProviderService.java
new file mode 100644
index 000000000..ac540217a
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/proxy/ProviderService.java
@@ -0,0 +1,44 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.consumer.proxy;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+/**
+ * 测试通过URL配置FeignClient
+ * 使用时修改provider-ip:provider-port配置
+ */
+@FeignClient(name = "provider", url = "http://127.0.0.1:18081", fallback = FeignClientFallback.class)
+public interface ProviderService {
+
+	@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
+	String echo(@PathVariable("str") String str);
+
+}
+
+@Component
+class FeignClientFallback implements ProviderService {
+	@Override
+	public String echo(String str) {
+		return "tsf-fault-tolerance-" + str;
+	}
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/resources/bootstrap.yml
new file mode 100644
index 000000000..b7cd3ee20
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/resources/bootstrap.yml
@@ -0,0 +1,17 @@
+server:
+  port: 18083
+spring:
+  application:
+    name: consumer-demo
+feign:
+  tsf:
+    enabled: true
+
+#本地测试时打开
+#tsf_namespace_id: default_namespace
+
+logging:
+  file:
+    name: /tsf-demo-logs/${spring.application.name}/root.log
+  level:
+    root: INFO
diff --git a/spring-cloud-tencent-examples/tsf-example/pom.xml b/spring-cloud-tencent-examples/tsf-example/pom.xml
new file mode 100644
index 000000000..41379d930
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+  ~
+  ~ Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+  ~
+  ~ Licensed under the BSD 3-Clause License (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ https://opensource.org/licenses/BSD-3-Clause
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software distributed
+  ~ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+  ~ CONDITIONS OF ANY KIND, either express or implied. See the License for the
+  ~ specific language governing permissions and limitations under the License.
+  -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<parent>
+		<artifactId>spring-cloud-tencent-examples</artifactId>
+		<groupId>com.tencent.cloud</groupId>
+		<version>${revision}</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+
+	<artifactId>tsf-example</artifactId>
+	<name>Spring Cloud Tencent TSF Examples</name>
+	<packaging>pom</packaging>
+
+	<properties>
+		<maven.deploy.skip>true</maven.deploy.skip>
+	</properties>
+
+	<modules>
+		<module>provider-demo</module>
+		<module>consumer-demo</module>
+	</modules>
+</project>
diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/pom.xml b/spring-cloud-tencent-examples/tsf-example/provider-demo/pom.xml
new file mode 100644
index 000000000..202b268a8
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		 xmlns="http://maven.apache.org/POM/4.0.0"
+		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>tsf-example</artifactId>
+		<groupId>com.tencent.cloud</groupId>
+		<version>${revision}</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<artifactId>provider-demo</artifactId>
+
+	<dependencies>
+		<dependency>
+			<groupId>com.tencent.cloud</groupId>
+			<artifactId>spring-cloud-starter-tencent-all</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+				<executions>
+					<execution>
+						<goals>
+							<goal>repackage</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<version>3.2.0</version>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+</project>
\ No newline at end of file
diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderApplication.java b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderApplication.java
new file mode 100644
index 000000000..accc1811e
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderApplication.java
@@ -0,0 +1,31 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.provider;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.tsf.annotation.EnableTsf;
+
+@SpringBootApplication
+@EnableTsf
+public class ProviderApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(ProviderApplication.class, args);
+	}
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderConfigController.java b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderConfigController.java
new file mode 100644
index 000000000..bfd49ba5f
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderConfigController.java
@@ -0,0 +1,36 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.provider;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RefreshScope
+public class ProviderConfigController {
+
+	@Value("${provider.name:default}")
+	private String name;
+
+	@GetMapping("/config/name")
+	public String getConfig() {
+		return name;
+	}
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderController.java b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderController.java
new file mode 100644
index 000000000..370975e42
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderController.java
@@ -0,0 +1,156 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package com.tencent.cloud.tsf.demo.provider;
+
+
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
+
+import javax.servlet.http.HttpServletResponse;
+
+import com.tencent.cloud.tsf.demo.provider.config.ProviderNameConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * @Author leoziltong@tencent.com
+ * @Date: 2021/5/11 17:10
+ */
+@RestController
+public class ProviderController {
+
+	private static final Logger LOG = LoggerFactory.getLogger(ProviderController.class);
+
+	@Value("${spring.application.name:}")
+	private String applicationName;
+
+	@Autowired
+	private ProviderNameConfig providerNameConfig;
+
+	// 获取本机ip
+	public static String getInet4Address() {
+		Enumeration<NetworkInterface> nis;
+		String ip = null;
+		try {
+			nis = NetworkInterface.getNetworkInterfaces();
+			for (; nis.hasMoreElements(); ) {
+				NetworkInterface ni = nis.nextElement();
+				Enumeration<InetAddress> ias = ni.getInetAddresses();
+				for (; ias.hasMoreElements(); ) {
+					InetAddress ia = ias.nextElement();
+					if (ia instanceof Inet4Address && !ia.getHostAddress().equals("127.0.0.1")) {
+						ip = ia.getHostAddress();
+					}
+				}
+			}
+		}
+		catch (SocketException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return ip;
+	}
+
+	@RequestMapping(value = "/hello", method = RequestMethod.GET)
+	public String hello() {
+		String echoHello = "say hello";
+		LOG.info(echoHello);
+		return echoHello;
+	}
+
+	@RequestMapping(value = "/echo/{param}", method = RequestMethod.GET)
+	public String echo(@PathVariable String param, HttpServletResponse response) throws IOException {
+		switch (param) {
+		case "1xx":
+			response.setStatus(HttpServletResponse.SC_CONTINUE);
+			response.getWriter().write("mock 1xx return.");
+			response.getWriter().flush();
+			return "mock 1xx return.";
+		case "3xx":
+			response.setStatus(HttpServletResponse.SC_FOUND);
+			response.getWriter().write("mock 3xx return.");
+			response.getWriter().flush();
+			return "mock 3xx return.";
+		case "4xx":
+			response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+			response.getWriter().write("mock 4xx return.");
+			response.getWriter().flush();
+			return "mock 4xx return.";
+		case "5xx":
+			response.setStatus(HttpServletResponse.SC_BAD_GATEWAY);
+			response.getWriter().write("mock 5xx return.");
+			response.getWriter().flush();
+			return "mock 5xx return.";
+		default:
+			LOG.info("provider-demo -- request param: [" + param + "]");
+			String result = "from host-ip: " + getInet4Address() + ", request param: " + param + ", response from " + providerNameConfig.getName();
+			LOG.info("provider-demo -- provider config name: [" + providerNameConfig.getName() + ']');
+			LOG.info("provider-demo -- response info: [" + result + "]");
+			return result;
+		}
+
+	}
+
+	@RequestMapping(value = "/echo/error/{param}", method = RequestMethod.GET)
+	public String echoError(@PathVariable String param) {
+		LOG.info("Error request param: [" + param + "], throw exception");
+
+		throw new RuntimeException("mock-ex");
+	}
+
+	/**
+	 * 延迟返回.
+	 * @param param 参数
+	 * @param delay 延时时间,单位毫秒
+	 * @throws InterruptedException InterruptedException
+	 */
+	@RequestMapping(value = "/echo/slow/{param}", method = RequestMethod.GET)
+	public String echoSlow(@PathVariable String param, @RequestParam(required = false) Integer delay) throws InterruptedException {
+		int sleepTime = delay == null ? 1000 : delay;
+		LOG.info("slow request param: [" + param + "], Start sleep: [" + sleepTime + "]ms");
+		Thread.sleep(sleepTime);
+		LOG.info("slow request param: [" + param + "], End sleep: [" + sleepTime + "]ms");
+
+		String result = "request param: " + param
+				+ ", slow response from " + applicationName
+				+ ", sleep: [" + sleepTime + "]ms";
+		return result;
+	}
+
+	@RequestMapping(value = "/echo/unit/{param}", method = RequestMethod.GET)
+	public String echoUnit(@PathVariable String param) {
+		LOG.info("provider-demo -- unit request param: [" + param + "]");
+		String result = "request param: " + param + ", response from " + applicationName;
+		LOG.info("provider-demo -- unit provider config name: [" + applicationName + ']');
+		LOG.info("provider-demo -- unit response info: [" + result + "]");
+		return result;
+	}
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/config/ProviderNameConfig.java b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/config/ProviderNameConfig.java
new file mode 100644
index 000000000..45c04f22c
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/config/ProviderNameConfig.java
@@ -0,0 +1,37 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.provider.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Component;
+
+@Component
+@RefreshScope
+@ConfigurationProperties(prefix = "provider.config")
+public class ProviderNameConfig {
+	private String name = "echo-provider-default-name";
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/config/ProviderNameConfigChangeListener.java b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/config/ProviderNameConfigChangeListener.java
new file mode 100644
index 000000000..1493c9105
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/config/ProviderNameConfigChangeListener.java
@@ -0,0 +1,40 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.provider.config;
+
+import com.tencent.tsf.consul.config.watch.ConfigChangeCallback;
+import com.tencent.tsf.consul.config.watch.ConfigChangeListener;
+import com.tencent.tsf.consul.config.watch.ConfigProperty;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigChangeListener(prefix = "provider.config", value = {"name"})
+public class ProviderNameConfigChangeListener implements ConfigChangeCallback {
+
+	private static final Logger log = LoggerFactory.getLogger(ProviderNameConfigChangeListener.class);
+
+	@Override
+	public void callback(ConfigProperty lastConfigProperty, ConfigProperty newConfigProperty) {
+		log.info("[TSF SDK] Configuration Change Listener: key: {}, old value: {}, new value: {}",
+				lastConfigProperty.getKey(), lastConfigProperty.getValue(), newConfigProperty.getValue());
+	}
+
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/controller/SwaggerApiController.java b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/controller/SwaggerApiController.java
new file mode 100644
index 000000000..be6cc6cd6
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/controller/SwaggerApiController.java
@@ -0,0 +1,145 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.provider.swagger.controller;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.Lists;
+import com.tencent.cloud.tsf.demo.provider.swagger.model.MessageBox;
+import com.tencent.cloud.tsf.demo.provider.swagger.model.MessageModel;
+import com.tencent.cloud.tsf.demo.provider.swagger.model.MessageUser;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController("/swagger")
+@Tag(description = "swagger 测试", name = "swaggerValue1")
+public class SwaggerApiController {
+
+	@RequestMapping(value = "/swagger/findMessages", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@Operation(method = "POST",
+			summary = "根据任务ID查询任务列表",
+			description = "根据任务ID查询任务列表Note")
+	public List<MessageModel> findMessages(@RequestBody
+	@Parameter(name = "msgIds", description = "消息ID列表") List<String> msgIds) {
+		List<MessageModel> messageModels = new ArrayList<>();
+		MessageModel messageModel = new MessageModel();
+		messageModel.setMsgContent("test1");
+		messageModel.setMsgId("1");
+		messageModel.setSendTime(System.currentTimeMillis());
+		MessageUser messageSender = new MessageUser();
+		messageSender.setEmail("abc@xxxx.com");
+		messageSender.setName("特朗普");
+		messageSender.setOfficeAddress("华盛顿白宫");
+		messageSender.setPhoneNum("911911911");
+		messageModel.setSendUser(messageSender);
+		MessageUser messageReceiver = new MessageUser();
+		messageReceiver.setEmail("abc@xxxx.com");
+		messageReceiver.setName("拜登");
+		messageReceiver.setOfficeAddress("华盛顿白宫");
+		messageReceiver.setPhoneNum("911911911");
+		messageModel.setReceiveUsers(Lists.newArrayList(messageReceiver));
+		messageModels.add(messageModel);
+		return messageModels;
+	}
+
+	//虽然这些@ExampleProperty和@Example属性已经在Swagger中实现,但Springfox还没有支持它们。问题仍然存在:
+	//https://github.com/springfox/springfox/issues/853
+	//https://github.com/springfox/springfox/issues/1536
+
+	@Operation(summary = "获取消息内容", method = "GET", description = "获取消息内容Note")
+	@ApiResponse(responseCode = "200", description = "abcdef", content = @Content(schema = @Schema(implementation = String.class)))
+	@RequestMapping("/swagger/getMessageContent")
+	public String getMessageContent(@RequestParam(name = "id")
+	@Parameter(description = "消息ID", name = "id") String msgId) {
+		return "abcdefg";
+	}
+
+	@Operation(summary = "获取消息详情", method = "GET", description = "获取消息内容Note")
+	@ApiResponses({@ApiResponse(responseCode = "200", description = "abcdef", content = @Content(schema = @Schema(implementation = MessageModel.class)))})
+	@RequestMapping(value = "/swagger/getMessageDetail", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	public MessageModel getMessageDetail(@RequestParam(name = "id")
+	@Parameter(description = "消息ID", name = "id") String msgId) {
+		MessageModel messageModel = new MessageModel();
+		messageModel.setMsgContent("test1");
+		messageModel.setMsgId("1");
+		messageModel.setSendTime(System.currentTimeMillis());
+		MessageUser messageSender = new MessageUser();
+		messageSender.setEmail("abc@xxxx.com");
+		messageSender.setName("特朗普");
+		messageSender.setOfficeAddress("华盛顿白宫");
+		messageSender.setPhoneNum("911911911");
+		messageModel.setSendUser(messageSender);
+		MessageUser messageReceiver = new MessageUser();
+		messageReceiver.setEmail("abc@xxxx.com");
+		messageReceiver.setName("拜登");
+		messageReceiver.setOfficeAddress("华盛顿白宫");
+		messageReceiver.setPhoneNum("911911911");
+		messageModel.setReceiveUsers(Lists.newArrayList(messageReceiver));
+		return messageModel;
+	}
+
+	@Operation(summary = "获取投递箱详情", method = "GET", description = "")
+	@ApiResponses({@ApiResponse(responseCode = "200", description = "获取投递箱成功", content = @Content(schema = @Schema(implementation = MessageBox.class)))})
+	@RequestMapping(value = "/swagger/getMessageBox", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	public MessageBox getMessageBox(@RequestParam @Parameter(required = true, description = "投递箱ID") String boxId,
+			@RequestParam @Parameter(name = "sizeLimit", example = "10", description = "投递箱最大投递数") int maxSizeLimit) {
+		return new MessageBox();
+	}
+
+	@Operation(summary = "获取投递箱详情V2", method = "POST", description = "")
+	@ApiResponses({@ApiResponse(responseCode = "200", description = "获取投递箱成功", content = @Content(schema = @Schema(implementation = MessageBox.class)))})
+	@RequestMapping(value = "/swagger/v2/getMessageBox", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	public MessageBox getMessageBoxV2(@RequestBody
+	@Parameter(required = true, name = "messageBox", example = "投递箱信息") MessageBox messageBox) {
+		return new MessageBox();
+	}
+
+	@Operation(summary = "获取投递箱详情V3", method = "POST", description = "")
+	@ApiResponses({@ApiResponse(responseCode = "200", description = "获取投递箱成功", content = @Content(schema = @Schema(implementation = Map.class)))})
+	@RequestMapping(value = "/swagger/v3/getMessageBox", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	public Map<String, Object> queryMessageBoxV3(@RequestBody
+	@Parameter(required = true, name = "messageBox", example = "投递箱信息") MessageBox messageBox) {
+
+		return new HashMap<>();
+	}
+
+
+	@Operation(summary = "获取投递箱地址", method = "GET", description = "")
+	@ApiResponses({@ApiResponse(responseCode = "200", description = "投递箱地址", content = @Content(schema = @Schema(implementation = String.class)))})
+	@RequestMapping(value = "/swagger/getMessageBoxAddress", produces = MediaType.TEXT_PLAIN_VALUE)
+	public String queryMessageBoxAddress(@RequestParam(name = "boxId")
+	@Parameter(description = "投递箱ID", name = "boxId", example = "box-qvp9htm5", required = true) String id) {
+		return "华盛顿白宫";
+
+	}
+
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/model/MessageBox.java b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/model/MessageBox.java
new file mode 100644
index 000000000..ec0a4ff05
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/model/MessageBox.java
@@ -0,0 +1,102 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.provider.swagger.model;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+@Schema(description = "消息投递箱")
+public class MessageBox {
+
+	@Schema(title = "默认失效天数", required = false)
+	private int expiredDays;
+
+	@Schema(title = "最大失效天数", required = false)
+	private Integer maxExpiredDays;
+
+	@Schema(title = "容量大小", required = false)
+	private Float capacity;
+
+	@Schema(title = "最大容量大小", required = false)
+	private float maxCapacity;
+
+	@Schema(title = "接受的信息数量", required = false)
+	private Double size;
+
+	@Schema(title = "最大接受的信息数量", required = false)
+	private double maxSize;
+
+	@Schema(title = "消息(循环测试嵌套对象)", required = false)
+	private MessageModel messageModel;
+
+	public int getExpiredDays() {
+		return expiredDays;
+	}
+
+	public void setExpiredDays(int expiredDays) {
+		this.expiredDays = expiredDays;
+	}
+
+	public Integer getMaxExpiredDays() {
+		return maxExpiredDays;
+	}
+
+	public void setMaxExpiredDays(Integer maxExpiredDays) {
+		this.maxExpiredDays = maxExpiredDays;
+	}
+
+	public Float getCapacity() {
+		return capacity;
+	}
+
+	public void setCapacity(Float capacity) {
+		this.capacity = capacity;
+	}
+
+	public float getMaxCapacity() {
+		return maxCapacity;
+	}
+
+	public void setMaxCapacity(float maxCapacity) {
+		this.maxCapacity = maxCapacity;
+	}
+
+	public Double getSize() {
+		return size;
+	}
+
+	public void setSize(Double size) {
+		this.size = size;
+	}
+
+	public double getMaxSize() {
+		return maxSize;
+	}
+
+	public void setMaxSize(double maxSize) {
+		this.maxSize = maxSize;
+	}
+
+	public MessageModel getMessageModel() {
+		return messageModel;
+	}
+
+	public void setMessageModel(MessageModel messageModel) {
+		this.messageModel = messageModel;
+	}
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/model/MessageModel.java b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/model/MessageModel.java
new file mode 100644
index 000000000..08d3a528e
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/model/MessageModel.java
@@ -0,0 +1,92 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.provider.swagger.model;
+
+import java.util.List;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+@Schema(description = "消息", title = "messageModel")
+public class MessageModel {
+
+	@Schema(name = "id", title = "消息ID", required = true, description = "消息ID notes")
+	private String msgId;
+
+	@Schema(title = "消息内容", required = false)
+	private String msgContent;
+
+	@Schema(title = "消息发送者", required = true)
+	private MessageUser sendUser;
+
+	@Schema(title = "消息接收者", required = true)
+	private List<MessageUser> receiveUsers;
+
+	@Schema(title = "消息发送时间", required = true)
+	private long sendTime;
+
+	@Schema(title = "消息投递箱", required = false)
+	private MessageBox messageBox;
+
+	public String getMsgId() {
+		return msgId;
+	}
+
+	public void setMsgId(String msgId) {
+		this.msgId = msgId;
+	}
+
+	public String getMsgContent() {
+		return msgContent;
+	}
+
+	public void setMsgContent(String msgContent) {
+		this.msgContent = msgContent;
+	}
+
+	public MessageUser getSendUser() {
+		return sendUser;
+	}
+
+	public void setSendUser(MessageUser sendUser) {
+		this.sendUser = sendUser;
+	}
+
+	public List<MessageUser> getReceiveUsers() {
+		return receiveUsers;
+	}
+
+	public void setReceiveUsers(List<MessageUser> receiveUsers) {
+		this.receiveUsers = receiveUsers;
+	}
+
+	public long getSendTime() {
+		return sendTime;
+	}
+
+	public void setSendTime(long sendTime) {
+		this.sendTime = sendTime;
+	}
+
+	public MessageBox getMessageBox() {
+		return messageBox;
+	}
+
+	public void setMessageBox(MessageBox messageBox) {
+		this.messageBox = messageBox;
+	}
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/model/MessageUser.java b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/model/MessageUser.java
new file mode 100644
index 000000000..9bd2f06ed
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/swagger/model/MessageUser.java
@@ -0,0 +1,69 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.tsf.demo.provider.swagger.model;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+@Schema(description = "消息发送/接收者")
+public class MessageUser {
+
+	@Schema(title = "用户姓名", name = "name")
+	private String name;
+
+	@Schema(title = "邮箱地址")
+	private String email;
+
+	@Schema(title = "电话号码")
+	private String phoneNum;
+
+	@Schema(title = "办公地址")
+	private String officeAddress;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getEmail() {
+		return email;
+	}
+
+	public void setEmail(String email) {
+		this.email = email;
+	}
+
+	public String getPhoneNum() {
+		return phoneNum;
+	}
+
+	public void setPhoneNum(String phoneNum) {
+		this.phoneNum = phoneNum;
+	}
+
+	public String getOfficeAddress() {
+		return officeAddress;
+	}
+
+	public void setOfficeAddress(String officeAddress) {
+		this.officeAddress = officeAddress;
+	}
+}
diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/resources/bootstrap.yml
new file mode 100644
index 000000000..9a4337fa3
--- /dev/null
+++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/resources/bootstrap.yml
@@ -0,0 +1,24 @@
+server:
+  port: 18081
+spring:
+  application:
+    name: provider-demo
+  cloud:
+    polaris:
+      namespace: default
+      enabled: true
+      stat:
+        enabled: true
+        port: 28081
+      loadbalancer:
+        strategy: polarisWeightedRandom
+    tencent:
+      rpc-enhancement:
+        reporter:
+          enabled: true
+
+logging:
+  file:
+    name: /tsf-demo-logs/${spring.application.name}/root.log
+  level:
+    root: INFO
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/pom.xml b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/pom.xml
index 59a313be9..416b4130c 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/pom.xml
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		 xmlns="http://maven.apache.org/POM/4.0.0"
 		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 	<parent>
 		<artifactId>spring-cloud-tencent-plugin-starters</artifactId>
@@ -17,12 +17,7 @@
 	<dependencies>
 		<dependency>
 			<groupId>com.tencent.cloud</groupId>
-			<artifactId>spring-cloud-tencent-polaris-context</artifactId>
-		</dependency>
-
-		<dependency>
-			<groupId>com.tencent.cloud</groupId>
-			<artifactId>spring-cloud-tencent-commons</artifactId>
+			<artifactId>spring-cloud-tencent-rpc-enhancement</artifactId>
 		</dependency>
 
 		<dependency>
@@ -52,12 +47,6 @@
 			<scope>test</scope>
 		</dependency>
 
-		<dependency>
-			<groupId>com.tencent.cloud</groupId>
-			<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
-			<optional>true</optional>
-		</dependency>
-
 		<dependency>
 			<groupId>com.tencent.polaris</groupId>
 			<artifactId>polaris-test-mock-discovery</artifactId>
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessProperties.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessProperties.java
index 3f2960883..89398f42a 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessProperties.java
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessProperties.java
@@ -23,7 +23,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
 @ConfigurationProperties("spring.cloud.polaris.lossless")
 public class LosslessProperties {
 
-	private boolean enabled = true;
+	private boolean enabled = false;
 
 	private int port = 28080;
 
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/resources/META-INF/spring.factories
index 1308d2ebb..fee2a497c 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/resources/META-INF/spring.factories
@@ -1,2 +1,4 @@
 org.springframework.cloud.bootstrap.BootstrapConfiguration=\
   com.tencent.cloud.plugin.lossless.config.LosslessPropertiesBootstrapConfiguration
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  com.tencent.cloud.plugin.lossless.config.LosslessAutoConfiguration
diff --git a/spring-cloud-tencent-polaris-context/pom.xml b/spring-cloud-tencent-polaris-context/pom.xml
index 50aa9dc1b..8f0f84e8c 100644
--- a/spring-cloud-tencent-polaris-context/pom.xml
+++ b/spring-cloud-tencent-polaris-context/pom.xml
@@ -21,11 +21,6 @@
 		</dependency>
 		<!-- Spring Cloud Tencent dependencies end -->
 
-		<dependency>
-			<groupId>org.springframework.cloud</groupId>
-			<artifactId>spring-cloud-starter-bootstrap</artifactId>
-		</dependency>
-
 		<!-- Polaris dependencies start -->
 		<dependency>
 			<groupId>com.tencent.polaris</groupId>
@@ -75,6 +70,11 @@
 			</exclusions>
 		</dependency>
 
+		<dependency>
+			<groupId>com.tencent.polaris</groupId>
+			<artifactId>connector-consul</artifactId>
+		</dependency>
+
 		<dependency>
 			<groupId>com.tencent.polaris</groupId>
 			<artifactId>connector-composite</artifactId>
@@ -109,13 +109,27 @@
 			<groupId>com.tencent.polaris</groupId>
 			<artifactId>polaris-assembly-factory</artifactId>
 		</dependency>
+		<dependency>
+			<groupId>com.tencent.polaris</groupId>
+			<artifactId>polaris-circuitbreaker-factory</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.tencent.polaris</groupId>
+			<artifactId>polaris-ratelimit-factory</artifactId>
+		</dependency>
 		<!-- Polaris dependencies end -->
 
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-bootstrap</artifactId>
+		</dependency>
+
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
+
 	</dependencies>
 
 </project>
diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/config/TsfCoreProperties.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/config/TsfCoreProperties.java
new file mode 100644
index 000000000..376ae0e51
--- /dev/null
+++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/config/TsfCoreProperties.java
@@ -0,0 +1,72 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.context.tsf.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Core properties.
+ *
+ * @author Haotian Zhang
+ */
+@ConfigurationProperties("tsf")
+public class TsfCoreProperties {
+
+	@Value("${tse_polaris_ip:}")
+	private String tsePolarisIp = "";
+
+	@Value("${tsf_consul_enable:false}")
+	private boolean tsfConsulEnable = false;
+
+	@Value("${tse_polaris_enable:false}")
+	private boolean tsePolarisEnable = false;
+
+	public String getTsePolarisIp() {
+		return tsePolarisIp;
+	}
+
+	public void setTsePolarisIp(String tsePolarisIp) {
+		this.tsePolarisIp = tsePolarisIp;
+	}
+
+	public boolean isTsfConsulEnable() {
+		return tsfConsulEnable;
+	}
+
+	public void setTsfConsulEnable(boolean tsfConsulEnable) {
+		this.tsfConsulEnable = tsfConsulEnable;
+	}
+
+	public boolean isTsePolarisEnable() {
+		return tsePolarisEnable;
+	}
+
+	public void setTsePolarisEnable(boolean tsePolarisEnable) {
+		this.tsePolarisEnable = tsePolarisEnable;
+	}
+
+	@Override
+	public String toString() {
+		return "TsfCoreProperties{" +
+				"tsePolarisIp='" + tsePolarisIp + '\'' +
+				", tsfConsulEnable=" + tsfConsulEnable +
+				", tsePolarisEnable=" + tsePolarisEnable +
+				'}';
+	}
+}
diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/config/TsfCorePropertiesAutoConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/config/TsfCorePropertiesAutoConfiguration.java
new file mode 100644
index 000000000..bb18aaf84
--- /dev/null
+++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/config/TsfCorePropertiesAutoConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.context.tsf.config;
+import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
+import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Core properties auto configuration.
+ *
+ * @author Haotian Zhang
+ */
+@Configuration(proxyBeanMethods = false)
+@AutoConfigureAfter(PolarisContextAutoConfiguration.class)
+@ConditionalOnTsfEnabled
+public class TsfCorePropertiesAutoConfiguration {
+
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfCoreProperties tsfCoreProperties() {
+		return new TsfCoreProperties();
+	}
+}
diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/config/TsfCorePropertiesBootstrapConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/config/TsfCorePropertiesBootstrapConfiguration.java
new file mode 100644
index 000000000..7b8054d6e
--- /dev/null
+++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/config/TsfCorePropertiesBootstrapConfiguration.java
@@ -0,0 +1,32 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.context.tsf.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * Core properties bootstrap configuration.
+ *
+ * @author Haotian Zhang
+ */
+@Configuration(proxyBeanMethods = false)
+@Import(TsfCorePropertiesAutoConfiguration.class)
+public class TsfCorePropertiesBootstrapConfiguration {
+
+}
diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/consul/TsfConsulAutoConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/consul/TsfConsulAutoConfiguration.java
new file mode 100644
index 000000000..612b9934e
--- /dev/null
+++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/consul/TsfConsulAutoConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.context.tsf.consul;
+
+import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableConfigurationProperties
+@ConditionalOnTsfEnabled
+public class TsfConsulAutoConfiguration {
+
+	static {
+		// 默认关闭对 discovery client(consul)的健康探测,避免 consul 故障时,影响监控探测
+		System.setProperty("spring.cloud.discovery.client.health-indicator.enabled", "false");
+	}
+
+	@Bean
+	@ConditionalOnMissingBean
+	public TsfConsulProperties tsfConsulProperties() {
+		return new TsfConsulProperties();
+	}
+}
diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/consul/TsfConsulBootstrapConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/consul/TsfConsulBootstrapConfiguration.java
new file mode 100644
index 000000000..594697a0c
--- /dev/null
+++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/consul/TsfConsulBootstrapConfiguration.java
@@ -0,0 +1,27 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.context.tsf.consul;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+@Configuration(proxyBeanMethods = false)
+@Import({TsfConsulAutoConfiguration.class})
+public class TsfConsulBootstrapConfiguration {
+
+}
diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/consul/TsfConsulProperties.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/consul/TsfConsulProperties.java
new file mode 100644
index 000000000..334b14f85
--- /dev/null
+++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/consul/TsfConsulProperties.java
@@ -0,0 +1,107 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.context.tsf.consul;
+
+
+import javax.validation.constraints.NotNull;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * @author Spencer Gibb
+ */
+@Validated
+public class TsfConsulProperties {
+
+	/** Consul agent hostname. Defaults to '127.0.0.1'. */
+	@Value("${tsf_consul_ip:${spring.cloud.consul.host:${SPRING_CLOUD_CONSUL_HOST:localhost}}}")
+	@NotNull
+	private String host = "localhost";
+
+	/**
+	 * Consul agent scheme (HTTP/HTTPS). If there is no scheme in address - client
+	 * will use HTTP.
+	 */
+	@Value("${spring.cloud.consul.scheme:${SPRING_CLOUD_CONSUL_SCHEME:}}")
+	private String scheme;
+
+	/** Consul agent port. Defaults to '8500'. */
+	@Value("${tsf_consul_port:${spring.cloud.consul.port:${SPRING_CLOUD_CONSUL_PORT:8500}}}")
+	@NotNull
+	private int port = 8500;
+
+	/** Is spring cloud consul enabled. */
+	@Value("${spring.cloud.consul.enabled:${SPRING_CLOUD_CONSUL_ENABLED:true}}")
+	private boolean enabled = true;
+
+	@Value("${tsf_consul_ttl_read_timeout:5000}")
+	private int ttlReadTimeout = 5000; // default 5s
+
+	public String getHost() {
+		return host;
+	}
+
+	public void setHost(String host) {
+		this.host = host;
+	}
+
+	public int getPort() {
+		return port;
+	}
+
+	public void setPort(int port) {
+		this.port = port;
+	}
+
+	public boolean isEnabled() {
+		return enabled;
+	}
+
+	public void setEnabled(boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	public String getScheme() {
+		return scheme;
+	}
+
+	public void setScheme(String scheme) {
+		this.scheme = scheme;
+	}
+
+	public int getTtlReadTimeout() {
+		return ttlReadTimeout;
+	}
+
+	public void setTtlReadTimeout(int ttlReadTimeout) {
+		this.ttlReadTimeout = ttlReadTimeout;
+	}
+
+
+	@Override
+	public String toString() {
+		return "ConsulProperties{" +
+				"host='" + host + '\'' +
+				", scheme='" + scheme + '\'' +
+				", port=" + port +
+				", enabled=" + enabled +
+				", ttlReadTimeout=" + ttlReadTimeout +
+				'}';
+	}
+}
diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/env/TsfCoreEnvironmentPostProcessor.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/env/TsfCoreEnvironmentPostProcessor.java
new file mode 100644
index 000000000..bb3f56c07
--- /dev/null
+++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/tsf/env/TsfCoreEnvironmentPostProcessor.java
@@ -0,0 +1,138 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package com.tencent.cloud.polaris.context.tsf.env;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.tencent.polaris.api.utils.StringUtils;
+import org.apache.commons.logging.Log;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor;
+import org.springframework.boot.env.EnvironmentPostProcessor;
+import org.springframework.boot.logging.DeferredLogFactory;
+import org.springframework.core.Ordered;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.MapPropertySource;
+
+/**
+ * Read TSF env.
+ *
+ * @author Haotian Zhang
+ */
+public final class TsfCoreEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
+
+	/**
+	 * run before {@link ConfigDataEnvironmentPostProcessor}.
+	 */
+	public static final int ORDER = ConfigDataEnvironmentPostProcessor.ORDER - 1;
+
+	private final Log LOGGER;
+
+	private TsfCoreEnvironmentPostProcessor(DeferredLogFactory logFactory) {
+		this.LOGGER = logFactory.getLog(getClass());
+	}
+
+	@Override
+	public int getOrder() {
+		return ORDER;
+	}
+
+	@Override
+	public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
+		String tsfAppId = environment.getProperty("tsf_app_id");
+		if (StringUtils.isNotBlank(tsfAppId)) {
+			Map<String, Object> defaultProperties = new HashMap<>();
+			//默认开启polaris
+			defaultProperties.put("spring.cloud.polaris.enabled", "true");
+			// tsf_application_id
+			String tsfApplicationId = environment.getProperty("tsf_application_id");
+			if (StringUtils.isBlank(tsfApplicationId)) {
+				LOGGER.error("tsf_application_id is empty");
+			}
+
+			// tsf_group_id
+			String tsfGroupId = environment.getProperty("tsf_group_id");
+			if (StringUtils.isBlank(tsfGroupId)) {
+				LOGGER.error("tsf_group_id is empty");
+			}
+
+			// tsf_namespace_id
+			String tsfNamespaceId = environment.getProperty("tsf_namespace_id");
+			if (StringUtils.isBlank(tsfNamespaceId)) {
+				LOGGER.error("tsf_namespace_id is empty");
+			}
+			else {
+				defaultProperties.put("spring.cloud.polaris.namespace", tsfNamespaceId);
+			}
+
+			// tsf_consul_ip
+			String tsfConsulIp = environment.getProperty("tsf_consul_ip");
+			if (StringUtils.isBlank(tsfConsulIp)) {
+				LOGGER.error("tsf_consul_ip is empty");
+			}
+
+			// tsf_consul_port
+			String tsfConsulPort = environment.getProperty("tsf_consul_port");
+			if (StringUtils.isBlank(tsfConsulPort)) {
+				LOGGER.error("tsf_consul_port is empty");
+			}
+
+			// tsf_token
+			String tsfConsulToken = environment.getProperty("tsf_token");
+			if (StringUtils.isBlank(tsfConsulToken)) {
+				LOGGER.error("tsf_token is empty");
+			}
+
+			// tse_polaris_enable
+			String tsePolarisEnable = environment.getProperty("tse_polaris_enable", "false");
+			if (StringUtils.equals(tsePolarisEnable, "true")) {
+				defaultProperties.put("spring.cloud.polaris.config.enabled", "true");
+			}
+			else {
+				defaultProperties.put("spring.cloud.polaris.contract.report.enabled", "false");
+				defaultProperties.put("spring.cloud.polaris.config.enabled", "true");
+				defaultProperties.put("spring.cloud.polaris.config.internal-enabled", "false");
+				defaultProperties.put("spring.cloud.polaris.config.data-source", "consul");
+				defaultProperties.put("spring.cloud.polaris.config.address", "http://" + tsfConsulIp + ":" + tsfConsulPort);
+				defaultProperties.put("spring.cloud.polaris.config.port", tsfConsulPort);
+				defaultProperties.put("spring.cloud.polaris.config.token", tsfConsulToken);
+				defaultProperties.put("spring.cloud.polaris.config.groups[0].namespace", "config");
+				defaultProperties.put("spring.cloud.polaris.config.groups[0].name", "application");
+				defaultProperties.put("spring.cloud.polaris.config.groups[0].files[0]", tsfApplicationId + "/" + tsfGroupId + "/");
+				defaultProperties.put("spring.cloud.polaris.config.groups[0].files[1]", tsfNamespaceId + "/");
+			}
+
+			// tse_polaris_ip
+			defaultProperties.put("spring.cloud.polaris.address", "grpc://" + environment.getProperty("tse_polaris_ip", "") + ":8091");
+
+			// tsf_sctt_extensions_port
+			defaultProperties.put("spring.cloud.polaris.stat.port", environment.getProperty("tsf_sctt_extensions_port", "11134"));
+
+			// rule based router fail over type
+			defaultProperties.put("spring.cloud.polaris.router.rule-router.fail-over", "none");
+
+			// namespace affinity router
+			defaultProperties.put("spring.cloud.polaris.router.namespace-router.enabled", "true");
+
+			MapPropertySource propertySource = new MapPropertySource("tsf-polaris-properties", defaultProperties);
+			environment.getPropertySources().addFirst(propertySource);
+		}
+	}
+}
diff --git a/spring-cloud-tencent-polaris-context/src/main/java/org/springframework/tsf/annotation/EnableTsf.java b/spring-cloud-tencent-polaris-context/src/main/java/org/springframework/tsf/annotation/EnableTsf.java
new file mode 100644
index 000000000..364695e73
--- /dev/null
+++ b/spring-cloud-tencent-polaris-context/src/main/java/org/springframework/tsf/annotation/EnableTsf.java
@@ -0,0 +1,45 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package org.springframework.tsf.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+
+/**
+ * Compatible with old versions TSF SDK.
+ *
+ * @author Haotian Zhang
+ */
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@EnableAutoConfiguration
+@EnableDiscoveryClient // 服务注册发现
+@EnableConfigurationProperties // 分布式配置
+public @interface EnableTsf {
+}
diff --git a/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories
index a121e3c26..185201262 100644
--- a/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories
@@ -1,7 +1,13 @@
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
   com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration,\
-  com.tencent.cloud.polaris.context.config.PolarisContextPostConfiguration
+  com.tencent.cloud.polaris.context.config.PolarisContextPostConfiguration,\
+  com.tencent.cloud.polaris.context.tsf.consul.TsfConsulAutoConfiguration,\
+  com.tencent.cloud.polaris.context.tsf.config.TsfCorePropertiesAutoConfiguration
 org.springframework.cloud.bootstrap.BootstrapConfiguration=\
-  com.tencent.cloud.polaris.context.config.PolarisContextBootstrapAutoConfiguration
+  com.tencent.cloud.polaris.context.config.PolarisContextBootstrapAutoConfiguration,\
+  com.tencent.cloud.polaris.context.tsf.config.TsfCorePropertiesBootstrapConfiguration,\
+  com.tencent.cloud.polaris.context.tsf.consul.TsfConsulBootstrapConfiguration
 org.springframework.context.ApplicationListener=\
   com.tencent.cloud.polaris.context.logging.PolarisLoggingApplicationListener
+org.springframework.boot.env.EnvironmentPostProcessor=\
+  com.tencent.cloud.polaris.context.tsf.env.TsfCoreEnvironmentPostProcessor