feat: support spring boot 1.5.x

pull/796/head
李剑鑫 3 years ago
parent 5212879079
commit 2948419b19

@ -33,6 +33,15 @@ import java.util.concurrent.atomic.AtomicReference;
*/ */
public class WebIpAndPortHolder { public class WebIpAndPortHolder {
private static boolean support = false;
static {
try {
Class.forName("org.springframework.boot.web.server.WebServer");
support = true;
} catch (Exception e) {
}
}
/** /**
* Application ip and application post * Application ip and application post
*/ */
@ -47,6 +56,9 @@ public class WebIpAndPortHolder {
} }
protected static void initIpAndPort() { protected static void initIpAndPort() {
if (!support) {
return;
}
webIpAndPort.compareAndSet(null, getWebIpAndPortInfo()); webIpAndPort.compareAndSet(null, getWebIpAndPortInfo());
} }
@ -83,7 +95,7 @@ public class WebIpAndPortHolder {
*/ */
public static boolean check(String nodes) { public static boolean check(String nodes) {
WebIpAndPortInfo webIpAndPort = WebIpAndPortHolder.getWebIpAndPort(); WebIpAndPortInfo webIpAndPort = WebIpAndPortHolder.getWebIpAndPort();
if (StringUtil.isEmpty(nodes) || ALL.equals(nodes)) { if (StringUtil.isEmpty(nodes) || ALL.equals(nodes) || webIpAndPort == null) {
return true; return true;
} }
String[] splitNodes = nodes.split(SEPARATOR); String[] splitNodes = nodes.split(SEPARATOR);

@ -49,10 +49,7 @@
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>

@ -0,0 +1 @@
<?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" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>cn.hippo4j</groupId> <artifactId>hippo4j-example</artifactId> <version>${revision}</version> </parent> <artifactId>hippo4j-config-nacos-spring-boot-1.5-starter-example</artifactId> <properties> <maven.deploy.skip>true</maven.deploy.skip> <spring-boot.version>1.5.22.RELEASE</spring-boot.version> <nacos-client.version>1.1.4</nacos-client.version> </properties> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>1.5.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>cn.hippo4j</groupId> <artifactId>hippo4j-example-core</artifactId> <version>${revision}</version> </dependency> <dependency> <groupId>cn.hippo4j</groupId> <artifactId>hippo4j-config-spring-boot-1.5-starter</artifactId> <version>${revision}</version> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-spring-legacy</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> </project>

@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 cn.hippo4j.example.config.nacos;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDynamicThreadPool
@SpringBootApplication(scanBasePackages = "cn.hippo4j.example.core")
public class ConfigNacosSpringBoot15ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigNacosSpringBoot15ExampleApplication.class, args);
}
}

@ -0,0 +1 @@
debug=true server.port=8089 server.servlet.context-path=/example management.metrics.export.prometheus.enabled=true management.server.port=29999 management.endpoints.web.exposure.include=* spring.profiles.active=dev spring.application.name=dynamic-threadpool-example spring.cloud.nacos.config.password=nacos spring.cloud.nacos.config.server-addr=127.0.0.1:8848 spring.cloud.nacos.config.username=nacos spring.cloud.nacos.config.extension-configs[0].data-id=hippo4j-nacos.yaml spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP spring.cloud.nacos.config.extension-configs[0].refresh=true spring.dynamic.thread-pool.enable=true spring.dynamic.thread-pool.banner=true spring.dynamic.thread-pool.collect=true spring.dynamic.thread-pool.collect-type=micrometer spring.dynamic.thread-pool.check-state-interval=5 spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT spring.dynamic.thread-pool.notify-platforms[0].secret-key=ac0426a5-c712-474c-9bff-72b8b8f5caff spring.dynamic.thread-pool.notify-platforms[1].platform=DING spring.dynamic.thread-pool.notify-platforms[1].secret-key=56417ebba6a27ca352f0de77a2ae9da66d01f39610b5ee8a6033c60ef9071c55 spring.dynamic.thread-pool.notify-platforms[2].platform=LARK spring.dynamic.thread-pool.notify-platforms[2].secret-key=2cbf2808-3839-4c26-a04d-fd201dd51f9e spring.dynamic.thread-pool.nacos.data-id=hippo4j-nacos.yaml spring.dynamic.thread-pool.nacos.group=DEFAULT_GROUP spring.dynamic.thread-pool.config-file-type=yml

@ -23,6 +23,7 @@
<module>hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq-example</module> <module>hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq-example</module>
<module>hippo4j-spring-boot-starter-adapter-rocketmq-example</module> <module>hippo4j-spring-boot-starter-adapter-rocketmq-example</module>
<module>hippo4j-config-etcd-spring-boot-starter-example</module> <module>hippo4j-config-etcd-spring-boot-starter-example</module>
<module>hippo4j-config-nacos-spring-boot-1.5-starter-example</module>
</modules> </modules>
<properties> <properties>

@ -0,0 +1 @@
<?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" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>cn.hippo4j</groupId> <artifactId>hippo4j-spring-boot</artifactId> <version>${revision}</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>hippo4j-config-spring-boot-1.5-starter</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <spring-boot.version>1.5.22.RELEASE</spring-boot.version> </properties> <dependencies> <dependency> <groupId>cn.hippo4j</groupId> <artifactId>hippo4j-config-spring-boot-starter</artifactId> <version>${revision}</version> </dependency> </dependencies> </project>

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 cn.hippo4j.config.springboot15x.starter.config;
import cn.hippo4j.config.springboot.starter.refresher.BootstrapConfigPropertiesBinderAdapt;
import cn.hippo4j.config.springboot15x.starter.refresher.SpringBoot15BootstrapConfigPropertiesBinderAdapt;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConfigHandlerConfiguration {
@Bean
@ConditionalOnClass(RelaxedDataBinder.class)
public BootstrapConfigPropertiesBinderAdapt bootstrapConfigPropertiesBinderAdapt() {
return new SpringBoot15BootstrapConfigPropertiesBinderAdapt();
}
}

@ -0,0 +1,109 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 cn.hippo4j.config.springboot15x.starter.refresher;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.refresher.BootstrapConfigPropertiesBinderAdapt;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.support.ResourceEditorRegistrar;
import org.springframework.boot.bind.CustomPropertyNamePatternsMatcher;
import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.boot.bind.RelaxedNames;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import java.beans.PropertyDescriptor;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* Bootstrap core properties binder adapt.
*/
public class SpringBoot15BootstrapConfigPropertiesBinderAdapt implements ApplicationContextAware, BootstrapConfigPropertiesBinderAdapt {
private ApplicationContext applicationContext;
/**
* Bootstrap core properties binder.
*
* @param configInfo
* @param bootstrapConfigProperties
* @return
*/
@Override
public BootstrapConfigProperties bootstrapCorePropertiesBinder(Map<Object, Object> configInfo, BootstrapConfigProperties bootstrapConfigProperties) {
BootstrapConfigProperties bindableCoreProperties = new BootstrapConfigProperties();
RelaxedNames relaxedNames = new RelaxedNames(BootstrapConfigProperties.PREFIX);
Set<String> names = getNames(bindableCoreProperties, relaxedNames);
// 绑定器
Map<String, Object> stringConfigInfo = new HashMap<>(configInfo.size());
configInfo.forEach((key, value) -> stringConfigInfo.put(key.toString(), value));
MapPropertySource test = new MapPropertySource("Hippo4j", stringConfigInfo);
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addFirst(test);
PropertyValues propertyValues = CustomPropertyNamePatternsMatcher.getPropertySourcesPropertyValues(names, propertySources);
RelaxedDataBinder dataBinder = new RelaxedDataBinder(bindableCoreProperties, BootstrapConfigProperties.PREFIX);
dataBinder.setAutoGrowCollectionLimit(Integer.MAX_VALUE);
dataBinder.setIgnoreNestedProperties(false);
dataBinder.setIgnoreInvalidFields(false);
dataBinder.setIgnoreUnknownFields(true);
ResourceEditorRegistrar resourceEditorRegistrar = new ResourceEditorRegistrar(applicationContext, applicationContext.getEnvironment());
resourceEditorRegistrar.registerCustomEditors(dataBinder);
dataBinder.bind(propertyValues);
return bindableCoreProperties;
}
private static Set<String> getNames(Object target, Iterable<String> prefixes) {
Set<String> names = new LinkedHashSet<>();
if (target != null) {
PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(target.getClass());
for (PropertyDescriptor descriptor : descriptors) {
String name = descriptor.getName();
if (!"class".equals(name)) {
RelaxedNames relaxedNames = RelaxedNames.forCamelCase(name);
if (prefixes == null) {
for (String relaxedName : relaxedNames) {
names.add(relaxedName);
}
} else {
for (String prefix : prefixes) {
for (String relaxedName : relaxedNames) {
names.add(prefix + "." + relaxedName);
names.add(prefix + "_" + relaxedName);
}
}
}
}
}
}
return names;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}

@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.boot.bind;
import org.springframework.beans.PropertyValues;
import org.springframework.boot.bind.DefaultPropertyNamePatternsMatcher;
import org.springframework.boot.bind.PropertyNamePatternsMatcher;
import org.springframework.boot.bind.PropertySourcesPropertyValues;
import org.springframework.core.env.MutablePropertySources;
import java.util.Set;
public class CustomPropertyNamePatternsMatcher {
private static final char[] EXACT_DELIMITERS = {'_', '.', '['};
public static PropertyValues getPropertySourcesPropertyValues(Set<String> names, MutablePropertySources propertySources) {
PropertyNamePatternsMatcher includes = getPropertyNamePatternsMatcher(names);
return new PropertySourcesPropertyValues(propertySources, names, includes, true);
}
private static PropertyNamePatternsMatcher getPropertyNamePatternsMatcher(Set<String> names) {
return new DefaultPropertyNamePatternsMatcher(EXACT_DELIMITERS, true, names);
}
}

@ -0,0 +1 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.hippo4j.config.springboot15x.starter.config.ConfigHandlerConfiguration

@ -19,6 +19,7 @@ package cn.hippo4j.config.springboot.starter.config;
import cn.hippo4j.config.springboot.starter.refresher.*; import cn.hippo4j.config.springboot.starter.refresher.*;
import com.alibaba.cloud.nacos.NacosConfigManager; import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.config.ConfigService;
import com.tencent.polaris.configuration.api.core.ConfigFileService; import com.tencent.polaris.configuration.api.core.ConfigFileService;
import io.etcd.jetcd.Client; import io.etcd.jetcd.Client;
@ -26,6 +27,7 @@ import lombok.RequiredArgsConstructor;
import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFramework;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -49,17 +51,21 @@ public class ConfigHandlerConfiguration {
private static final String POLARIS = "config.serverConnector"; private static final String POLARIS = "config.serverConnector";
@Bean
@ConditionalOnMissingBean
public BootstrapConfigPropertiesBinderAdapt bootstrapConfigPropertiesBinderAdapt() {
return new DefaultBootstrapConfigPropertiesBinderAdapt();
}
@RequiredArgsConstructor @RequiredArgsConstructor
@ConditionalOnClass(ConfigService.class) @ConditionalOnClass(ConfigService.class)
@ConditionalOnMissingClass(NACOS_CONFIG_MANAGER_KEY) @ConditionalOnMissingClass(NACOS_CONFIG_MANAGER_KEY)
@ConditionalOnProperty(prefix = BootstrapConfigProperties.PREFIX, name = NACOS_DATA_ID_KEY) @ConditionalOnProperty(prefix = BootstrapConfigProperties.PREFIX, name = NACOS_DATA_ID_KEY)
static class EmbeddedNacos { static class EmbeddedNacos {
public final BootstrapConfigProperties bootstrapConfigProperties;
@Bean @Bean
public NacosRefresherHandler nacosRefresherHandler() { public NacosRefresherHandler nacosRefresherHandler(NacosConfigProperties nacosConfigProperties) {
return new NacosRefresherHandler(bootstrapConfigProperties); return new NacosRefresherHandler(nacosConfigProperties);
} }
} }

@ -59,11 +59,7 @@ import org.springframework.core.annotation.Order;
@ConditionalOnBean(MarkerConfiguration.Marker.class) @ConditionalOnBean(MarkerConfiguration.Marker.class)
@EnableConfigurationProperties(BootstrapConfigProperties.class) @EnableConfigurationProperties(BootstrapConfigProperties.class)
@ConditionalOnProperty(prefix = BootstrapConfigProperties.PREFIX, value = "enable", matchIfMissing = true, havingValue = "true") @ConditionalOnProperty(prefix = BootstrapConfigProperties.PREFIX, value = "enable", matchIfMissing = true, havingValue = "true")
@Import({ @Import({ConfigHandlerConfiguration.class})
ConfigHandlerConfiguration.EmbeddedNacos.class, ConfigHandlerConfiguration.EmbeddedNacosCloud.class,
ConfigHandlerConfiguration.EmbeddedApollo.class, ConfigHandlerConfiguration.EmbeddedZookeeper.class,
ConfigHandlerConfiguration.EmbeddedEtcd.class
})
@ImportAutoConfiguration({WebAdapterConfiguration.class, UtilAutoConfiguration.class, MessageConfiguration.class, LocalLogMonitorConfiguration.class, MicrometerMonitorConfiguration.class}) @ImportAutoConfiguration({WebAdapterConfiguration.class, UtilAutoConfiguration.class, MessageConfiguration.class, LocalLogMonitorConfiguration.class, MicrometerMonitorConfiguration.class})
public class DynamicThreadPoolAutoConfiguration { public class DynamicThreadPoolAutoConfiguration {

@ -37,19 +37,21 @@ import java.util.concurrent.ExecutorService;
* Abstract core thread-pool dynamic refresh. * Abstract core thread-pool dynamic refresh.
*/ */
@Slf4j @Slf4j
@RequiredArgsConstructor
public abstract class AbstractConfigThreadPoolDynamicRefresh public abstract class AbstractConfigThreadPoolDynamicRefresh
implements implements
ThreadPoolDynamicRefresh, ThreadPoolDynamicRefresh,
ThreadPoolInitRefresh, ThreadPoolInitRefresh,
InitializingBean { InitializingBean {
protected final BootstrapConfigProperties bootstrapConfigProperties; private final BootstrapConfigPropertiesBinderAdapt bootstrapConfigPropertiesBinderAdapt;
protected BootstrapConfigProperties bootstrapConfigProperties;
protected final ExecutorService dynamicRefreshExecutorService = ThreadPoolBuilder.builder().singlePool("client.dynamic.refresh").build(); protected final ExecutorService dynamicRefreshExecutorService = ThreadPoolBuilder.builder().singlePool("client.dynamic.refresh").build();
public AbstractConfigThreadPoolDynamicRefresh() { public AbstractConfigThreadPoolDynamicRefresh() {
bootstrapConfigProperties = ApplicationContextHolder.getBean(BootstrapConfigProperties.class); bootstrapConfigProperties = ApplicationContextHolder.getBean(BootstrapConfigProperties.class);
bootstrapConfigPropertiesBinderAdapt = ApplicationContextHolder.getBean(BootstrapConfigPropertiesBinderAdapt.class);
} }
@Override @Override
@ -69,7 +71,7 @@ public abstract class AbstractConfigThreadPoolDynamicRefresh
if (CollectionUtil.isNotEmpty(newValueChangeMap)) { if (CollectionUtil.isNotEmpty(newValueChangeMap)) {
Optional.ofNullable(configInfo).ifPresent(each -> each.putAll(newValueChangeMap)); Optional.ofNullable(configInfo).ifPresent(each -> each.putAll(newValueChangeMap));
} }
BootstrapConfigProperties bindableCoreProperties = BootstrapConfigPropertiesBinderAdapt.bootstrapCorePropertiesBinder(configInfo, bootstrapConfigProperties); BootstrapConfigProperties bindableCoreProperties = bootstrapConfigPropertiesBinderAdapt.bootstrapCorePropertiesBinder(configInfo, bootstrapConfigProperties);
ApplicationContextHolder.getInstance().publishEvent(new Hippo4jConfigDynamicRefreshEvent(this, bindableCoreProperties)); ApplicationContextHolder.getInstance().publishEvent(new Hippo4jConfigDynamicRefreshEvent(this, bindableCoreProperties));
} catch (Exception ex) { } catch (Exception ex) {
log.error("Hippo-4J core dynamic refresh failed.", ex); log.error("Hippo-4J core dynamic refresh failed.", ex);

@ -17,142 +17,11 @@
package cn.hippo4j.config.springboot.starter.refresher; package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties; import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.config.DynamicThreadPoolNotifyProperties;
import cn.hippo4j.config.springboot.starter.config.ExecutorProperties;
import cn.hippo4j.config.springboot.starter.config.NotifyPlatformProperties;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
/** public interface BootstrapConfigPropertiesBinderAdapt {
* Bootstrap core properties binder adapt.
*/
public class BootstrapConfigPropertiesBinderAdapt {
/**
* Bootstrap core properties binder.
*
* @param configInfo
* @param bootstrapConfigProperties
* @return
*/
public static BootstrapConfigProperties bootstrapCorePropertiesBinder(Map<Object, Object> configInfo, BootstrapConfigProperties bootstrapConfigProperties) {
BootstrapConfigProperties bindableCoreProperties = null;
try {
ConfigurationPropertySource sources = new MapConfigurationPropertySource(configInfo);
Binder binder = new Binder(sources);
bindableCoreProperties = binder.bind(BootstrapConfigProperties.PREFIX, Bindable.ofInstance(bootstrapConfigProperties)).get();
} catch (Exception ex) {
try {
Class.forName("org.springframework.boot.context.properties.bind.Binder");
} catch (ClassNotFoundException notEx) {
bindableCoreProperties = adapt(configInfo);
}
}
return bindableCoreProperties;
}
/**
* SpringBoot 1.5.x, , PR.
*
* @param configInfo
* @return
*/
@Deprecated
private static BootstrapConfigProperties adapt(Map<Object, Object> configInfo) {
BootstrapConfigProperties bindableConfigProperties;
try {
// filter
Map<Object, Object> targetMap = new HashMap<>();
configInfo.forEach((key, val) -> {
boolean containFlag = key != null
&& StringUtil.isNotBlank((String) key)
&& (((String) key).indexOf(BootstrapConfigProperties.PREFIX + ".executors") != -1
|| ((String) key).indexOf(BootstrapConfigProperties.PREFIX + ".notify-platforms") != -1
|| ((String) key).indexOf(BootstrapConfigProperties.PREFIX + ".notifyPlatforms") != -1);
if (containFlag) {
String targetKey = key.toString().replace(BootstrapConfigProperties.PREFIX + ".", "");
targetMap.put(targetKey, val);
}
});
// convert
List<ExecutorProperties> executorPropertiesList = new ArrayList<>();
List<NotifyPlatformProperties> notifyPropertiesList = new ArrayList<>();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
Map<String, Object> executorSingleMap = new HashMap<>();
Map<String, Object> platformSingleMap = new HashMap<>();
Map<String, Object> notifySingleMap = new HashMap<>();
for (Map.Entry entry : targetMap.entrySet()) {
String key = entry.getKey().toString();
if (key.indexOf("executors[" + i + "].") != -1) {
if (key.indexOf("executors[" + i + "].notify.") != -1) {
key = key.replace("executors[" + i + "].notify.", "");
String[] notifyKeySplit = key.split("-");
if (notifyKeySplit != null && notifyKeySplit.length > 0) {
key = key.replace("-", "_");
}
notifySingleMap.put(key, entry.getValue());
} else {
key = key.replace("executors[" + i + "].", "");
String[] keySplit = key.split("-"); BootstrapConfigProperties bootstrapCorePropertiesBinder(Map<Object, Object> configInfo, BootstrapConfigProperties bootstrapConfigProperties);
if (keySplit != null && keySplit.length > 0) {
key = key.replace("-", "_");
}
executorSingleMap.put(key, entry.getValue());
}
}
if (key.indexOf("notify-platforms[" + i + "].") != -1 || key.indexOf("notifyPlatforms[" + i + "].") != -1) {
if (key.indexOf("notify-platforms[" + i + "].") != -1) {
key = key.replace("notify-platforms[" + i + "].", "");
} else {
key = key.replace("notifyPlatforms[" + i + "].", "");
}
String[] keySplit = key.split("-");
if (keySplit != null && keySplit.length > 0) {
key = key.replace("-", "_");
}
platformSingleMap.put(key, entry.getValue());
}
}
if (CollectionUtil.isEmpty(executorSingleMap) && CollectionUtil.isEmpty(platformSingleMap)) {
break;
}
if (CollectionUtil.isNotEmpty(executorSingleMap)) {
ExecutorProperties executorProperties = BeanUtil.mapToBean(executorSingleMap, ExecutorProperties.class, true);
if (executorProperties != null) {
if (CollectionUtil.isNotEmpty(notifySingleMap)) {
DynamicThreadPoolNotifyProperties alarm = BeanUtil.mapToBean(notifySingleMap, DynamicThreadPoolNotifyProperties.class, true);
alarm.setReceives(alarm.getReceives());
executorProperties.setNotify(alarm);
}
executorPropertiesList.add(executorProperties);
}
}
if (CollectionUtil.isNotEmpty(platformSingleMap)) {
NotifyPlatformProperties notifyPlatformProperties = BeanUtil.mapToBean(platformSingleMap, NotifyPlatformProperties.class, true);
if (notifyPlatformProperties != null) {
notifyPropertiesList.add(notifyPlatformProperties);
}
}
}
bindableConfigProperties = new BootstrapConfigProperties();
bindableConfigProperties.setExecutors(executorPropertiesList);
bindableConfigProperties.setNotifyPlatforms(notifyPropertiesList);
} catch (Exception ex) {
throw ex;
}
return bindableConfigProperties;
}
} }

@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
import java.util.Map;
/**
* Bootstrap core properties binder adapt.
*/
public class DefaultBootstrapConfigPropertiesBinderAdapt implements BootstrapConfigPropertiesBinderAdapt {
/**
* Bootstrap core properties binder.
*
* @param configInfo
* @param bootstrapConfigProperties
* @return
*/
@Override
public BootstrapConfigProperties bootstrapCorePropertiesBinder(Map<Object, Object> configInfo, BootstrapConfigProperties bootstrapConfigProperties) {
ConfigurationPropertySource sources = new MapConfigurationPropertySource(configInfo);
Binder binder = new Binder(sources);
return binder.bind(BootstrapConfigProperties.PREFIX, Bindable.ofInstance(bootstrapConfigProperties)).get();
}
}

@ -18,6 +18,7 @@
package cn.hippo4j.config.springboot.starter.refresher; package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties; import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.annotation.NacosInjected; import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener; import com.alibaba.nacos.api.config.listener.Listener;
@ -38,8 +39,9 @@ public class NacosRefresherHandler extends AbstractConfigThreadPoolDynamicRefres
@NacosInjected @NacosInjected
private ConfigService configService; private ConfigService configService;
public NacosRefresherHandler(BootstrapConfigProperties bootstrapConfigProperties) { public NacosRefresherHandler(NacosConfigProperties nacosConfigProperties) {
super(bootstrapConfigProperties); super();
this.configService = nacosConfigProperties.configServiceInstance();
} }
@Override @Override
@ -47,7 +49,7 @@ public class NacosRefresherHandler extends AbstractConfigThreadPoolDynamicRefres
Map<String, String> nacosConfig = bootstrapConfigProperties.getNacos(); Map<String, String> nacosConfig = bootstrapConfigProperties.getNacos();
String dataId = nacosConfig.get(DATA_ID); String dataId = nacosConfig.get(DATA_ID);
String group = nacosConfig.get(GROUP); String group = nacosConfig.get(GROUP);
return configService.getConfig(dataId, group, Long.MAX_VALUE); return configService.getConfig(dataId, group, 60 * 10000);
} }
@Override @Override

@ -15,5 +15,6 @@
<module>hippo4j-spring-boot-starter</module> <module>hippo4j-spring-boot-starter</module>
<module>hippo4j-spring-boot-starter-adapter</module> <module>hippo4j-spring-boot-starter-adapter</module>
<module>hippo4j-spring-boot-starter-monitor</module> <module>hippo4j-spring-boot-starter-monitor</module>
<module>hippo4j-config-spring-boot-1.5-starter</module>
</modules> </modules>
</project> </project>

Loading…
Cancel
Save