Commit 5ea92a89 authored by liaozan's avatar liaozan 🏀

Refactor auto configuration property loading

parent cdcdefb2
...@@ -16,51 +16,51 @@ import static java.util.stream.Collectors.*; ...@@ -16,51 +16,51 @@ import static java.util.stream.Collectors.*;
@Slf4j @Slf4j
public class StreamUtils { public class StreamUtils {
public static <T> List<T> filterToList(Collection<T> data, Predicate<T> predicate) { public static <T> List<T> filterToList(Iterable<T> data, Predicate<T> predicate) {
return filter(data, predicate, Collectors.toList()); return filter(data, predicate, Collectors.toList());
} }
public static <T> Set<T> filterToSet(Collection<T> data, Predicate<T> predicate) { public static <T> Set<T> filterToSet(Iterable<T> data, Predicate<T> predicate) {
return filter(data, predicate, Collectors.toSet()); return filter(data, predicate, Collectors.toSet());
} }
public static <T, C extends Collection<T>> C filter(Collection<T> data, Predicate<T> predicate, Collector<T, ?, C> collector) { public static <T, C extends Iterable<T>> C filter(Iterable<T> data, Predicate<T> predicate, Collector<T, ?, C> collector) {
return Optional.ofNullable(data).orElse(emptyList()).stream().filter(predicate).collect(collector); return from(data).filter(predicate).collect(collector);
} }
public static <T, E> List<E> toList(Collection<T> data, Function<T, E> mapper) { public static <T, E> List<E> toList(Iterable<T> data, Function<T, E> mapper) {
return toList(data, mapper, false); return toList(data, mapper, false);
} }
public static <T, E> List<E> toList(Collection<T> data, Function<T, E> mapper, boolean distinct) { public static <T, E> List<E> toList(Iterable<T> data, Function<T, E> mapper, boolean distinct) {
return toList(data, mapper, distinct, false); return toList(data, mapper, distinct, false);
} }
public static <T, E> List<E> toList(Collection<T> data, Function<T, E> mapper, boolean distinct, boolean ignoreNull) { public static <T, E> List<E> toList(Iterable<T> data, Function<T, E> mapper, boolean distinct, boolean ignoreNull) {
return extract(data, mapper, distinct, ignoreNull, Collectors.toList()); return extract(data, mapper, distinct, ignoreNull, Collectors.toList());
} }
public static <T, E> Set<E> toSet(Collection<T> data, Function<T, E> mapper) { public static <T, E> Set<E> toSet(Iterable<T> data, Function<T, E> mapper) {
return toSet(data, mapper, false); return toSet(data, mapper, false);
} }
public static <T, E> Set<E> toSet(Collection<T> data, Function<T, E> mapper, boolean ignoreNull) { public static <T, E> Set<E> toSet(Iterable<T> data, Function<T, E> mapper, boolean ignoreNull) {
return extract(data, mapper, ignoreNull, false, Collectors.toSet()); return extract(data, mapper, ignoreNull, false, Collectors.toSet());
} }
public static <K, T> Map<K, T> toMap(Collection<T> data, Function<T, K> keyMapper) { public static <K, T> Map<K, T> toMap(Iterable<T> data, Function<T, K> keyMapper) {
return toMap(data, keyMapper, false); return toMap(data, keyMapper, false);
} }
public static <K, T> Map<K, T> toMap(Collection<T> data, Function<T, K> keyMapper, boolean ordered) { public static <K, T> Map<K, T> toMap(Iterable<T> data, Function<T, K> keyMapper, boolean ordered) {
return toMap(data, keyMapper, Function.identity(), ordered); return toMap(data, keyMapper, Function.identity(), ordered);
} }
public static <K, T, V> Map<K, V> toMap(Collection<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper) { public static <K, T, V> Map<K, V> toMap(Iterable<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper) {
return toMap(data, keyMapper, valueMapper, false); return toMap(data, keyMapper, valueMapper, false);
} }
public static <K, T, V> Map<K, V> toMap(Collection<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, boolean ordered) { public static <K, T, V> Map<K, V> toMap(Iterable<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, boolean ordered) {
Supplier<Map<K, V>> mapFactory = HashMap::new; Supplier<Map<K, V>> mapFactory = HashMap::new;
if (ordered) { if (ordered) {
mapFactory = LinkedHashMap::new; mapFactory = LinkedHashMap::new;
...@@ -68,74 +68,67 @@ public class StreamUtils { ...@@ -68,74 +68,67 @@ public class StreamUtils {
return toMap(data, keyMapper, valueMapper, mapFactory); return toMap(data, keyMapper, valueMapper, mapFactory);
} }
public static <K, T, V, M extends Map<K, V>> Map<K, V> toMap(Collection<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, Supplier<M> mapFactory) { public static <K, T, V, M extends Map<K, V>> Map<K, V> toMap(Iterable<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, Supplier<M> mapFactory) {
return Optional.ofNullable(data) return from(data).collect(Collectors.toMap(keyMapper, valueMapper, (oldValue, newValue) -> {
.orElse(emptyList())
.stream()
.collect(Collectors.toMap(keyMapper, valueMapper, (oldValue, newValue) -> {
// Could not get the key when mergeFunction invoke // Could not get the key when mergeFunction invoke
log.warn("There are multiple values with the same key when toMap, return the old one"); log.warn("There are multiple values with the same key when toMap, return the old one");
return oldValue; return oldValue;
}, mapFactory)); }, mapFactory));
} }
public static <K, T> Map<K, List<T>> groupBy(Collection<T> data, Function<T, K> mapper) { public static <K, T> Map<K, List<T>> groupBy(Iterable<T> data, Function<T, K> mapper) {
return groupBy(data, mapper, false); return groupBy(data, mapper, false);
} }
public static <K, T> Map<K, List<T>> groupBy(Collection<T> data, Function<T, K> keyMapper, boolean ignoreNullKey) { public static <K, T> Map<K, List<T>> groupBy(Iterable<T> data, Function<T, K> keyMapper, boolean ignoreNullKey) {
return groupBy(data, keyMapper, Collectors.toList(), ignoreNullKey); return groupBy(data, keyMapper, Collectors.toList(), ignoreNullKey);
} }
public static <K, T, V> Map<K, V> groupBy(Collection<T> data, Function<T, K> mapper, Collector<T, ?, V> collectors) { public static <K, T, V> Map<K, V> groupBy(Iterable<T> data, Function<T, K> mapper, Collector<T, ?, V> collectors) {
return groupBy(data, mapper, collectors, false); return groupBy(data, mapper, collectors, false);
} }
public static <K, T, V> Map<K, V> groupBy(Collection<T> data, Function<T, K> mapper, Collector<T, ?, V> collectors, boolean ignoreNullKey) { public static <K, T, V> Map<K, V> groupBy(Iterable<T> data, Function<T, K> mapper, Collector<T, ?, V> collectors, boolean ignoreNullKey) {
return groupBy(data, mapper, Function.identity(), collectors, ignoreNullKey); return groupBy(data, mapper, Function.identity(), collectors, ignoreNullKey);
} }
public static <K, T, V> Map<K, List<V>> groupBy(Collection<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper) { public static <K, T, V> Map<K, List<V>> groupBy(Iterable<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper) {
return groupBy(data, keyMapper, valueMapper, Collectors.toList(), false); return groupBy(data, keyMapper, valueMapper, Collectors.toList(), false);
} }
public static <K, T, V> Map<K, List<V>> groupBy(Collection<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, boolean ignoreNullKey) { public static <K, T, V> Map<K, List<V>> groupBy(Iterable<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, boolean ignoreNullKey) {
return groupBy(data, keyMapper, valueMapper, Collectors.toList(), ignoreNullKey); return groupBy(data, keyMapper, valueMapper, Collectors.toList(), ignoreNullKey);
} }
public static <K, T, V, C> Map<K, C> groupBy(Collection<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, Collector<V, ?, C> collector) { public static <K, T, V, C> Map<K, C> groupBy(Iterable<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, Collector<V, ?, C> collector) {
return groupBy(data, keyMapper, valueMapper, collector, false); return groupBy(data, keyMapper, valueMapper, collector, false);
} }
public static <K, T, V, C> Map<K, C> groupBy(Collection<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, Collector<V, ?, C> collector, boolean ignoreNullKey) { public static <K, T, V, C> Map<K, C> groupBy(Iterable<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, Collector<V, ?, C> collector, boolean ignoreNullKey) {
return groupBy(data, keyMapper, valueMapper, collector, ignoreNullKey, HashMap::new); return groupBy(data, keyMapper, valueMapper, collector, ignoreNullKey, HashMap::new);
} }
public static <K, T, V, C> Map<K, C> groupBy(Collection<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, Collector<V, ?, C> collector, boolean ignoreNullKey, Supplier<Map<K, C>> mapSupplier) { public static <K, T, V, C> Map<K, C> groupBy(Iterable<T> data, Function<T, K> keyMapper, Function<T, V> valueMapper, Collector<V, ?, C> collector, boolean ignoreNullKey, Supplier<Map<K, C>> mapSupplier) {
Stream<T> stream = Optional.ofNullable(data) Stream<T> stream = from(data);
.orElse(emptyList())
.stream();
if (ignoreNullKey) { if (ignoreNullKey) {
stream = stream.filter(item -> null != keyMapper.apply(item)); stream = stream.filter(item -> null != keyMapper.apply(item));
} }
return stream.collect(groupingBy(keyMapper, mapSupplier, mapping(valueMapper, collector))); return stream.collect(groupingBy(keyMapper, mapSupplier, mapping(valueMapper, collector)));
} }
public static <T> String join(Collection<T> data, CharSequence delimiter) { public static <T> String join(Iterable<T> data, CharSequence delimiter) {
return join(data, delimiter, Objects::toString); return join(data, delimiter, Objects::toString);
} }
public static <T> String join(Collection<T> data, CharSequence delimiter, Function<T, ? extends CharSequence> toStringFunction) { public static <T> String join(Iterable<T> data, CharSequence delimiter, Function<T, ? extends CharSequence> toStringFunction) {
return join(data, delimiter, "", "", toStringFunction); return join(data, delimiter, "", "", toStringFunction);
} }
public static <T> String join(Collection<T> data, CharSequence delimiter, String prefix, String suffix, Function<T, ? extends CharSequence> toStringFunction) { public static <T> String join(Iterable<T> data, CharSequence delimiter, String prefix, String suffix, Function<T, ? extends CharSequence> toStringFunction) {
return Optional.ofNullable(data) return from(data).map(toStringFunction).collect(joining(delimiter, prefix, suffix));
.orElse(emptyList())
.stream().map(toStringFunction).collect(joining(delimiter, prefix, suffix));
} }
public static <T, E, R> R extract(Collection<T> data, Function<T, E> mapper, boolean distinct, boolean ignoreNull, Collector<E, ?, R> collector) { public static <T, E, R> R extract(Iterable<T> data, Function<T, E> mapper, boolean distinct, boolean ignoreNull, Collector<E, ?, R> collector) {
Predicate<E> predicate = null; Predicate<E> predicate = null;
if (ignoreNull) { if (ignoreNull) {
predicate = Objects::nonNull; predicate = Objects::nonNull;
...@@ -143,11 +136,8 @@ public class StreamUtils { ...@@ -143,11 +136,8 @@ public class StreamUtils {
return extract(data, mapper, predicate, distinct, collector); return extract(data, mapper, predicate, distinct, collector);
} }
public static <T, E, R> R extract(Collection<T> data, Function<T, E> mapper, Predicate<E> predicate, boolean distinct, Collector<E, ?, R> collector) { public static <T, E, R> R extract(Iterable<T> data, Function<T, E> mapper, Predicate<E> predicate, boolean distinct, Collector<E, ?, R> collector) {
Stream<E> stream = Optional.ofNullable(data) Stream<E> stream = from(data).map(mapper);
.orElse(emptyList())
.stream()
.map(mapper);
if (distinct) { if (distinct) {
stream = stream.distinct(); stream = stream.distinct();
} }
...@@ -157,4 +147,13 @@ public class StreamUtils { ...@@ -157,4 +147,13 @@ public class StreamUtils {
return stream.collect(collector); return stream.collect(collector);
} }
public static <T> Stream<T> from(Iterable<T> iterable) {
return from(iterable, false);
}
public static <T> Stream<T> from(Iterable<T> iterable, boolean parallel) {
Iterable<T> source = Optional.ofNullable(iterable).orElse(emptyList());
return StreamSupport.stream(source.spliterator(), parallel);
}
} }
\ No newline at end of file
package com.schbrain.common.util.properties; package com.schbrain.common.util.properties;
import com.schbrain.common.util.ConfigurationPropertiesUtils;
import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MapPropertySource;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
/** /**
...@@ -13,12 +13,12 @@ import java.util.Map; ...@@ -13,12 +13,12 @@ import java.util.Map;
*/ */
public class SchbrainMapPropertySource extends MapPropertySource { public class SchbrainMapPropertySource extends MapPropertySource {
public SchbrainMapPropertySource(String name, Object source) { public SchbrainMapPropertySource(String name, Map<String, String> source) {
this(name, ConfigurationPropertiesUtils.toMap(source)); super(name, new LinkedHashMap<>(source));
} }
public SchbrainMapPropertySource(String name, Map<String, Object> source) { public void addProperties(Map<String, String> properties) {
super(name, source); getSource().putAll(properties);
} }
} }
\ No newline at end of file
...@@ -2,55 +2,39 @@ package com.schbrain.common.util.support; ...@@ -2,55 +2,39 @@ package com.schbrain.common.util.support;
import com.schbrain.common.util.ConfigurationPropertiesUtils; import com.schbrain.common.util.ConfigurationPropertiesUtils;
import lombok.Data; import lombok.Data;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.BindHandler; import org.springframework.boot.context.properties.bind.*;
import org.springframework.boot.context.properties.bind.Binder; import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
import java.beans.Introspector;
/** /**
* <b> WARNING!!! </b>
* <p>
* If you want to use a subclass of this class before {@link BeanPostProcessor},
* please load it through {@link com.schbrain.framework.autoconfigure.apollo.util.ConfigUtils}
*
* @author liaozan * @author liaozan
* @since 2022/1/10 * @since 2022/1/10
*/ */
@Data @Data
public abstract class ConfigurableProperties { public abstract class ConfigurableProperties implements Ordered {
/** /**
* the namespace of remote config * get the namespace of remote config
*/
protected String namespace = getDefaultNamespace();
/**
* the prefix of properties
*/ */
protected String prefix = getPossiblePrefix(); public abstract String getDefaultNamespace();
/** /**
* the name of propertySource * bind properties
*/ */
protected String name = Introspector.decapitalize(getClass().getSimpleName()); public ConfigurableProperties bind(ConfigurableEnvironment environment) {
return Binder.get(environment, bindHandler()).bindOrCreate(getPropertiesPrefix(), Bindable.ofInstance(this));
public String getDefaultNamespace() {
return "application";
}
@SuppressWarnings({"unchecked", "unused"})
public <T extends ConfigurableProperties> T bindOrCreate(ConfigurableEnvironment environment, boolean afterMerge) {
return (T) Binder.get(environment, bindHandler()).bindOrCreate(getPrefix(), getClass());
} }
protected BindHandler bindHandler() { @Override
return BindHandler.DEFAULT; public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
} }
private String getPossiblePrefix() { /**
* the prefix of properties
*/
protected String getPropertiesPrefix() {
ConfigurationProperties annotation = getClass().getAnnotation(ConfigurationProperties.class); ConfigurationProperties annotation = getClass().getAnnotation(ConfigurationProperties.class);
if (annotation == null) { if (annotation == null) {
String className = ConfigurationProperties.class.getName(); String className = ConfigurationProperties.class.getName();
...@@ -60,4 +44,11 @@ public abstract class ConfigurableProperties { ...@@ -60,4 +44,11 @@ public abstract class ConfigurableProperties {
return ConfigurationPropertiesUtils.getPrefix(getClass()); return ConfigurationPropertiesUtils.getPrefix(getClass());
} }
/**
* get the {@link org.springframework.boot.context.properties.bind.BindHandler} for bind
*/
protected BindHandler bindHandler() {
return BindHandler.DEFAULT;
}
} }
\ No newline at end of file
...@@ -9,9 +9,9 @@ import java.lang.annotation.*; ...@@ -9,9 +9,9 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE}) @Target({ElementType.METHOD, ElementType.TYPE})
public @interface IgnoreLogin { public @interface IgnoreLogin {
/** /**
* 是否忽略登录 * 是否忽略登录
* @return
*/ */
boolean ignore() default true; boolean ignore() default true;
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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"> 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> <modelVersion>4.0.0</modelVersion>
......
...@@ -34,21 +34,6 @@ ...@@ -34,21 +34,6 @@
"description": "encoding for request\/response", "description": "encoding for request\/response",
"sourceType": "com.schbrain.common.web.properties.WebProperties" "sourceType": "com.schbrain.common.web.properties.WebProperties"
}, },
{
"name": "schbrain.web.name",
"type": "java.lang.String",
"sourceType": "com.schbrain.common.web.properties.WebProperties"
},
{
"name": "schbrain.web.namespace",
"type": "java.lang.String",
"sourceType": "com.schbrain.common.web.properties.WebProperties"
},
{
"name": "schbrain.web.prefix",
"type": "java.lang.String",
"sourceType": "com.schbrain.common.web.properties.WebProperties"
},
{ {
"name": "schbrain.web.wrap-response", "name": "schbrain.web.wrap-response",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
......
com.schbrain.common.util.support.ConfigurableProperties=\
com.schbrain.common.web.properties.WebProperties
\ No newline at end of file
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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/maven-v4_0_0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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"> 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> <modelVersion>4.0.0</modelVersion>
......
...@@ -52,6 +52,8 @@ ...@@ -52,6 +52,8 @@
<schbrain-common-util.version>${revision}</schbrain-common-util.version> <schbrain-common-util.version>${revision}</schbrain-common-util.version>
<schbrain-common.version>${revision}</schbrain-common.version> <schbrain-common.version>${revision}</schbrain-common.version>
<schbrain-dubbo.version>${revision}</schbrain-dubbo.version> <schbrain-dubbo.version>${revision}</schbrain-dubbo.version>
<schbrain-elasticsearch.version>${revision}</schbrain-elasticsearch.version>
<schbrain-kafka.version>${revision}</schbrain-kafka.version>
<schbrain-logger.version>${revision}</schbrain-logger.version> <schbrain-logger.version>${revision}</schbrain-logger.version>
<schbrain-module-tree.version>${revision}</schbrain-module-tree.version> <schbrain-module-tree.version>${revision}</schbrain-module-tree.version>
<schbrain-mybatis.version>${revision}</schbrain-mybatis.version> <schbrain-mybatis.version>${revision}</schbrain-mybatis.version>
...@@ -151,8 +153,13 @@ ...@@ -151,8 +153,13 @@
<!-- 二方包 --> <!-- 二方包 -->
<dependency> <dependency>
<groupId>com.schbrain.framework</groupId> <groupId>com.schbrain.framework</groupId>
<artifactId>schbrain-spring-support</artifactId> <artifactId>apollo-spring-boot-starter</artifactId>
<version>${schbrain-spring-support.version}</version> <version>${schbrain-apollo.version}</version>
</dependency>
<dependency>
<groupId>com.schbrain.framework</groupId>
<artifactId>cache-spring-boot-starter</artifactId>
<version>${schbrain-cache.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.schbrain.framework</groupId> <groupId>com.schbrain.framework</groupId>
...@@ -161,19 +168,24 @@ ...@@ -161,19 +168,24 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.schbrain.framework</groupId> <groupId>com.schbrain.framework</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId> <artifactId>elasticsearch-spring-boot-starter</artifactId>
<version>${schbrain-mybatis.version}</version> <version>${schbrain-elasticsearch.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.schbrain.framework</groupId> <groupId>com.schbrain.framework</groupId>
<artifactId>apollo-spring-boot-starter</artifactId> <artifactId>kafka-spring-boot-starter</artifactId>
<version>${schbrain-apollo.version}</version> <version>${schbrain-kafka.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.schbrain.framework</groupId> <groupId>com.schbrain.framework</groupId>
<artifactId>logger-spring-boot-starter</artifactId> <artifactId>logger-spring-boot-starter</artifactId>
<version>${schbrain-logger.version}</version> <version>${schbrain-logger.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.schbrain.framework</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${schbrain-mybatis.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.schbrain.framework</groupId> <groupId>com.schbrain.framework</groupId>
<artifactId>oss-spring-boot-starter</artifactId> <artifactId>oss-spring-boot-starter</artifactId>
...@@ -186,13 +198,13 @@ ...@@ -186,13 +198,13 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.schbrain.framework</groupId> <groupId>com.schbrain.framework</groupId>
<artifactId>cache-spring-boot-starter</artifactId> <artifactId>schbrain-base-dao</artifactId>
<version>${schbrain-cache.version}</version> <version>${schbrain-base-dao.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.schbrain.framework</groupId> <groupId>com.schbrain.framework</groupId>
<artifactId>schbrain-base-dao</artifactId> <artifactId>schbrain-spring-support</artifactId>
<version>${schbrain-base-dao.version}</version> <version>${schbrain-spring-support.version}</version>
</dependency> </dependency>
<!-- 三方包 --> <!-- 三方包 -->
...@@ -650,6 +662,32 @@ ...@@ -650,6 +662,32 @@
</plugins> </plugins>
</pluginManagement> </pluginManagement>
<plugins> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-configuration-metadata</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.build.outputDirectory}/META-INF</directory>
<includes>
<include>spring-configuration-metadata.json</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<outputDirectory>${project.basedir}/src/main/resources/META-INF</outputDirectory>
<overwrite>true</overwrite>
</configuration>
</execution>
</executions>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId> <artifactId>maven-source-plugin</artifactId>
......
package com.schbrain.framework.autoconfigure.apollo; package com.schbrain.framework.autoconfigure.apollo;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig; import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import com.ctrip.framework.apollo.spring.boot.ApolloAutoConfiguration;
import com.ctrip.framework.apollo.spring.config.PropertySourcesConstants; import com.ctrip.framework.apollo.spring.config.PropertySourcesConstants;
import com.schbrain.framework.autoconfigure.apollo.properties.ApolloProperties; import com.schbrain.framework.autoconfigure.apollo.properties.ApolloProperties;
import com.schbrain.framework.autoconfigure.apollo.properties.ConfigurationPropertiesRegistry;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
...@@ -15,10 +13,10 @@ import org.springframework.context.annotation.Import; ...@@ -15,10 +13,10 @@ import org.springframework.context.annotation.Import;
* @since 2021/11/15 * @since 2021/11/15
*/ */
@EnableApolloConfig @EnableApolloConfig
@Import({SchbrainPropertySourcesProcessor.class, ConfigurationPropertiesRegistry.class}) @Import(ConfigurationPropertiesRegistry.class)
@EnableConfigurationProperties(ApolloProperties.class) @EnableConfigurationProperties(ApolloProperties.class)
@AutoConfiguration(before = ApolloAutoConfiguration.class) @AutoConfiguration(before = com.ctrip.framework.apollo.spring.boot.ApolloAutoConfiguration.class)
@ConditionalOnProperty(value = PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED, matchIfMissing = true) @ConditionalOnProperty(value = PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED, matchIfMissing = true)
public class SchbrainApolloAutoConfiguration { public class ApolloAutoConfiguration {
} }
\ No newline at end of file
package com.schbrain.framework.autoconfigure.apollo.properties; package com.schbrain.framework.autoconfigure.apollo;
import com.ctrip.framework.foundation.Foundation; import com.ctrip.framework.foundation.Foundation;
import com.schbrain.common.util.ApplicationName; import com.schbrain.common.util.ApplicationName;
import com.schbrain.common.util.EnvUtils; import com.schbrain.common.util.EnvUtils;
import com.schbrain.framework.support.spring.EnvironmentPostProcessorAdapter; import com.schbrain.framework.support.spring.EnvironmentPostProcessorLoggerAwareAdapter;
import com.schbrain.framework.support.spring.defaults.DefaultPropertiesEnvironmentPostProcessor;
import org.springframework.boot.ConfigurableBootstrapContext; import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor;
import org.springframework.boot.logging.DeferredLogFactory; import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
...@@ -24,34 +23,37 @@ import static com.ctrip.framework.apollo.spring.config.PropertySourcesConstants. ...@@ -24,34 +23,37 @@ import static com.ctrip.framework.apollo.spring.config.PropertySourcesConstants.
* @author liaozan * @author liaozan
* @since 2021/11/6 * @since 2021/11/6
*/ */
public class ApolloPropertiesPreparer extends EnvironmentPostProcessorAdapter implements Ordered { public class ApolloConfigurationInitializer extends EnvironmentPostProcessorLoggerAwareAdapter implements Ordered {
// get properties after configData loaded /**
public static final Integer ORDER = ConfigDataEnvironmentPostProcessor.ORDER + 1; * load properties after set the default properties
public static final String ENV_KEY = "env"; */
private static final Map<String, Object> INIT_PROPERTIES = new LinkedHashMap<>(); public static final Integer DEFAULT_ORDER = DefaultPropertiesEnvironmentPostProcessor.DEFAULT_ORDER + 1;
private static final String ENV_KEY = "env";
private static Map<String, Object> INIT_PROPERTIES = new LinkedHashMap<>();
private final ConfigurablePropertiesLoader configurablePropertiesLoader;
public ApolloPropertiesPreparer(DeferredLogFactory deferredLogFactory, ConfigurableBootstrapContext bootstrapContext) { public ApolloConfigurationInitializer(DeferredLogFactory deferredLogFactory, ConfigurableBootstrapContext bootstrapContext) {
super(deferredLogFactory, bootstrapContext); super(deferredLogFactory, bootstrapContext);
this.configurablePropertiesLoader = new ConfigurablePropertiesLoader(getDeferredLogFactory());
} }
@Override @Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
if (disabled(environment)) { if (disabled(environment)) {
print("apollo is disabled"); print(APOLLO_BOOTSTRAP_ENABLED + " is disabled");
return; return;
} }
setRequiredProperty(environment); setRequiredProperty(environment);
configurablePropertiesLoader.load(environment, application);
} }
@Override @Override
public int getOrder() { public int getOrder() {
return ORDER; return DEFAULT_ORDER;
}
@Override
protected void onBootstrapContextClosed(ConfigurableApplicationContext context) {
context.getBeanFactory().addBeanPostProcessor(new ConfigurablePropertiesBeanPostProcessor(context));
} }
private boolean disabled(ConfigurableEnvironment environment) { private boolean disabled(ConfigurableEnvironment environment) {
...@@ -71,8 +73,11 @@ public class ApolloPropertiesPreparer extends EnvironmentPostProcessorAdapter im ...@@ -71,8 +73,11 @@ public class ApolloPropertiesPreparer extends EnvironmentPostProcessorAdapter im
saveProperty(APOLLO_BOOTSTRAP_EAGER_LOAD_ENABLED, true); saveProperty(APOLLO_BOOTSTRAP_EAGER_LOAD_ENABLED, true);
saveProperty(APOLLO_BOOTSTRAP_ENABLED, true); saveProperty(APOLLO_BOOTSTRAP_ENABLED, true);
saveProperty(APOLLO_CACHE_FILE_ENABLE, true);
saveProperty(APOLLO_PROPERTY_ORDER_ENABLE, true); saveProperty(APOLLO_PROPERTY_ORDER_ENABLE, true);
saveProperty(APOLLO_PROPERTY_NAMES_CACHE_ENABLE, true); // DO NOT set to true. After caching the property name, SpringBoot may not be able to bind the properties
saveProperty(APOLLO_PROPERTY_NAMES_CACHE_ENABLE, false);
saveProperty(APOLLO_OVERRIDE_SYSTEM_PROPERTIES, false);
printProperties(); printProperties();
} }
...@@ -84,6 +89,7 @@ public class ApolloPropertiesPreparer extends EnvironmentPostProcessorAdapter im ...@@ -84,6 +89,7 @@ public class ApolloPropertiesPreparer extends EnvironmentPostProcessorAdapter im
private void printProperties() { private void printProperties() {
INIT_PROPERTIES.forEach((k, v) -> print(k + " : " + v)); INIT_PROPERTIES.forEach((k, v) -> print(k + " : " + v));
INIT_PROPERTIES = null;
} }
private void print(String message) { private void print(String message) {
...@@ -120,7 +126,11 @@ public class ApolloPropertiesPreparer extends EnvironmentPostProcessorAdapter im ...@@ -120,7 +126,11 @@ public class ApolloPropertiesPreparer extends EnvironmentPostProcessorAdapter im
} }
private String getEnv(ConfigurableEnvironment environment) { private String getEnv(ConfigurableEnvironment environment) {
return EnvUtils.getProfile(environment); String profile = EnvUtils.getProfile(environment);
if (profile == null) {
profile = EnvUtils.DEVELOPMENT;
}
return profile;
} }
private String getAppId(ConfigurableEnvironment environment) { private String getAppId(ConfigurableEnvironment environment) {
......
...@@ -12,7 +12,7 @@ import org.springframework.core.env.ConfigurableEnvironment; ...@@ -12,7 +12,7 @@ import org.springframework.core.env.ConfigurableEnvironment;
* @since 2022/4/19 * @since 2022/4/19
*/ */
@Order(ApolloApplicationContextInitializer.DEFAULT_ORDER + 1) @Order(ApolloApplicationContextInitializer.DEFAULT_ORDER + 1)
public class SchbrainApolloPropertiesEnvironmentPostProcessor implements EnvironmentPostProcessor { public class ApolloPropertiesReorderEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override @Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
......
package com.schbrain.framework.autoconfigure.apollo;
import cn.hutool.core.thread.GlobalThreadPool;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService;
import com.schbrain.common.util.properties.SchbrainMapPropertySource;
import com.schbrain.common.util.support.ConfigurableProperties;
import com.schbrain.framework.autoconfigure.apollo.listener.PropertiesPreparedEvent;
import com.schbrain.framework.autoconfigure.apollo.listener.PropertiesPreparedEventListener;
import com.schbrain.framework.autoconfigure.apollo.properties.ApolloProperties;
import com.schbrain.framework.autoconfigure.apollo.util.ConfigUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.logging.Log;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.ClassUtils;
import java.util.List;
import static org.springframework.core.io.support.SpringFactoriesLoader.loadFactories;
/**
* @author liaozan
* @since 2023-04-29
*/
class ConfigurablePropertiesLoader {
/**
* the name of properties propertySource
*/
private static final String PROPERTIES_PROPERTY_SOURCE = "ConfigurablePropertiesPropertySource";
private final Log log;
ConfigurablePropertiesLoader(DeferredLogFactory logFactory) {
this.log = logFactory.getLog(ConfigurablePropertiesLoader.class);
}
void load(ConfigurableEnvironment environment, SpringApplication application) {
List<ConfigurableProperties> configurableProperties = loadFactories(ConfigurableProperties.class, getClass().getClassLoader());
if (CollectionUtils.isEmpty(configurableProperties)) {
log.warn("There is no configuration properties found");
return;
}
ApplicationEventMulticaster eventMulticaster = createEventMulticaster(application);
ApolloProperties apolloProperties = ApolloProperties.get(environment);
// MUST NOT use CachedCompositePropertySource
CompositePropertySource compositePropertySource = new CompositePropertySource(PROPERTIES_PROPERTY_SOURCE);
if (apolloProperties.isRemoteFirst()) {
environment.getPropertySources().addFirst(compositePropertySource);
} else {
environment.getPropertySources().addLast(compositePropertySource);
}
configurableProperties.forEach(properties -> {
String namespace = properties.getDefaultNamespace();
Config config = ConfigService.getConfig(namespace);
SchbrainMapPropertySource propertySource = ConfigUtils.toPropertySource(namespace, config);
if (propertySource == null) {
log.warn("No configuration properties loaded under namespace: " + namespace);
return;
}
ConfigUtils.resolvePlaceHolders(environment, propertySource);
// early add to environment to support properties bind
compositePropertySource.addPropertySource(propertySource);
ConfigurableProperties boundProperties = properties.bind(environment);
eventMulticaster.multicastEvent(new PropertiesPreparedEvent(boundProperties, propertySource, environment, application));
});
}
private ApplicationEventMulticaster createEventMulticaster(SpringApplication application) {
SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster();
eventMulticaster.setTaskExecutor(GlobalThreadPool.getExecutor());
for (ApplicationListener<?> listener : application.getListeners()) {
if (ClassUtils.isAssignableValue(PropertiesPreparedEventListener.class, listener)) {
eventMulticaster.addApplicationListener(listener);
}
}
return eventMulticaster;
}
}
\ No newline at end of file
package com.schbrain.framework.autoconfigure.apollo.properties; package com.schbrain.framework.autoconfigure.apollo;
import cn.hutool.core.text.StrPool; import cn.hutool.core.text.StrPool;
import com.ctrip.framework.apollo.spring.property.SpringValue; import com.ctrip.framework.apollo.spring.property.SpringValue;
......
package com.schbrain.framework.autoconfigure.apollo;
import com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor;
import com.schbrain.framework.autoconfigure.apollo.util.PropertySourceOrderUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* @author liaozan
* @since 2021/12/6
*/
public class SchbrainPropertySourcesProcessor extends PropertySourcesProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
super.postProcessBeanFactory(beanFactory);
PropertySourceOrderUtils.adjustPropertySourceOrder(beanFactory.getBean(ConfigurableEnvironment.class));
}
}
\ No newline at end of file
package com.schbrain.framework.autoconfigure.apollo.listener;
import com.schbrain.common.util.properties.SchbrainMapPropertySource;
import com.schbrain.common.util.support.ConfigurableProperties;
import lombok.Getter;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationEvent;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* @author liaozan
* @since 2023-04-28
*/
@Getter
public class PropertiesPreparedEvent extends ApplicationEvent {
private static final long serialVersionUID = 2567291189881702459L;
private final ConfigurableEnvironment environment;
private final SchbrainMapPropertySource propertySource;
private final SpringApplication application;
public PropertiesPreparedEvent(ConfigurableProperties properties, SchbrainMapPropertySource propertySource,
ConfigurableEnvironment environment, SpringApplication application) {
super(properties);
this.environment = environment;
this.propertySource = propertySource;
this.application = application;
}
public ConfigurableProperties getConfigurableProperties() {
return (ConfigurableProperties) getSource();
}
}
\ No newline at end of file
package com.schbrain.framework.autoconfigure.apollo.listener;
import org.springframework.context.ApplicationListener;
/**
* @author liaozan
* @since 2023-04-29
*/
public interface PropertiesPreparedEventListener extends ApplicationListener<PropertiesPreparedEvent> {
}
\ No newline at end of file
package com.schbrain.framework.autoconfigure.apollo.listener;
import com.schbrain.common.util.support.ConfigurableProperties;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* @author liaozan
* @since 2023-04-28
*/
@SuppressWarnings("unchecked")
public class PropertiesPreparedEventListenerAdapter<T extends ConfigurableProperties> implements PropertiesPreparedEventListener {
private final Class<T> propertyType;
public PropertiesPreparedEventListenerAdapter() {
ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
this.propertyType = (Class<T>) actualTypeArguments[0];
}
@Override
public void onApplicationEvent(PropertiesPreparedEvent event) {
if (event.getConfigurableProperties().getClass() == propertyType) {
onPropertiesPrepared(event, (T) event.getConfigurableProperties());
}
}
protected void onPropertiesPrepared(PropertiesPreparedEvent event, T configurableProperties) {
}
}
\ No newline at end of file
package com.schbrain.framework.autoconfigure.apollo.properties;
import com.schbrain.common.util.support.ConfigurableProperties;
import com.schbrain.framework.autoconfigure.apollo.util.ConfigUtils;
import com.schbrain.framework.support.spring.BeanPostProcessorAdapter;
import org.springframework.context.ConfigurableApplicationContext;
/**
* @author liaozan
* @since 2022/9/16
*/
public class ConfigurablePropertiesBeanPostProcessor extends BeanPostProcessorAdapter<ConfigurableProperties> {
public ConfigurablePropertiesBeanPostProcessor(ConfigurableApplicationContext applicationContext) {
this.setApplicationContext(applicationContext);
}
@Override
protected ConfigurableProperties doPostProcessBeforeInstantiation(Class<ConfigurableProperties> beanClass) {
return ConfigUtils.loadConfig(environment, beanClass);
}
}
\ No newline at end of file
package com.schbrain.framework.autoconfigure.apollo.util; package com.schbrain.framework.autoconfigure.apollo.util;
import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService; import com.google.common.collect.Maps;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import com.schbrain.common.util.ConfigurationPropertiesUtils;
import com.schbrain.common.util.properties.SchbrainMapPropertySource; import com.schbrain.common.util.properties.SchbrainMapPropertySource;
import com.schbrain.common.util.support.ConfigurableProperties; import lombok.extern.slf4j.Slf4j;
import com.schbrain.framework.autoconfigure.apollo.properties.ApolloProperties; import org.springframework.core.env.ConfigurableEnvironment;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.DefaultPropertiesPropertySource;
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
import org.springframework.core.env.*;
import java.util.LinkedHashMap; import javax.annotation.Nullable;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import static com.ctrip.framework.apollo.core.ApolloClientSystemConsts.APP_ID;
/** /**
* @author liaozan * @author liaozan
* @since 2021/12/6 * @since 2021/12/6
*/ */
@Slf4j
public class ConfigUtils { public class ConfigUtils {
private static final Log LOGGER = LogFactory.getLog(ConfigUtils.class); @Nullable
public static SchbrainMapPropertySource toPropertySource(String name, Config config) {
private static final boolean APOLLO_DISABLED = System.getProperty(APP_ID) == null; Set<String> propertyNames = config.getPropertyNames();
if (propertyNames.isEmpty()) {
public static boolean isApolloDisabled() { return null;
return APOLLO_DISABLED;
}
public static <T extends ConfigurableProperties> T loadConfig(ConfigurableEnvironment environment, Class<T> propertyClass) {
// load default and local properties
T target = BeanUtils.instantiateClass(propertyClass).bindOrCreate(environment, false);
Map<String, Object> defaultProperties = ConfigurationPropertiesUtils.toMap(target);
// load remote config
Map<String, Object> loadedProperties = loadConfig(target.getNamespace(), target.getPrefix());
// merge
ApolloProperties apolloProperties = ApolloProperties.get(environment);
Map<String, Object> mergedProperties = mergeProperties(loadedProperties, defaultProperties, apolloProperties.isRemoteFirst());
// add to environment
addToEnvironment(environment, target.getName(), mergedProperties);
// rebind after addToEnvironment
return target.bindOrCreate(environment, true);
}
public static Map<String, Object> loadConfig(String namespace) {
return loadConfig(namespace, null);
}
public static Map<String, Object> loadConfig(String namespace, String prefix) {
if (isApolloDisabled()) {
return new LinkedHashMap<>();
}
Config config = ConfigService.getConfig(namespace);
if (config.getSourceType() == ConfigSourceType.LOCAL) {
LOGGER.warn(String.format("Failed to get config from Apollo namespace: %s, will use the local cache value", namespace));
}
Map<String, Object> configs = new LinkedHashMap<>();
for (String propertyName : config.getPropertyNames()) {
if (prefix != null) {
if (!propertyName.startsWith(prefix)) {
continue;
}
} }
String propertyValue = config.getProperty(propertyName, null); Map<String, String> configs = Maps.newLinkedHashMapWithExpectedSize(propertyNames.size());
configs.put(propertyName, propertyValue); for (String propertyName : propertyNames) {
String property = config.getProperty(propertyName, null);
configs.put(propertyName, property);
} }
return configs; return new SchbrainMapPropertySource(name, configs);
} }
public static <T extends ConfigurableProperties> void addToEnvironment(ConfigurableEnvironment environment, T properties) { public static void resolvePlaceHolders(ConfigurableEnvironment environment, SchbrainMapPropertySource propertySource) {
addToEnvironment(environment, new SchbrainMapPropertySource(properties.getName(), properties));
}
public static void addToEnvironment(ConfigurableEnvironment environment, String name, Map<String, Object> properties) {
addToEnvironment(environment, new SchbrainMapPropertySource(name, properties));
}
public static void addToEnvironment(ConfigurableEnvironment environment, MapPropertySource propertySource) {
MutablePropertySources propertySources = environment.getPropertySources();
String propertySourceName = propertySource.getName();
boolean alreadyExist = propertySources.contains(propertySourceName);
if (alreadyExist) {
PropertySource<?> existing = propertySources.get(propertySourceName);
if (existing instanceof MapPropertySource) {
Map<String, Object> existingSource = ((MapPropertySource) existing).getSource();
existingSource.putAll(propertySource.getSource());
} else {
LOGGER.warn("Existing propertySource is not an instance of MapPropertySource, overwrite existing...");
propertySources.replace(propertySourceName, propertySource);
}
} else {
propertySources.addLast(propertySource);
}
resolvePlaceHolders(environment, propertySource);
ConfigurationPropertySources.attach(environment);
DefaultPropertiesPropertySource.moveToEnd(environment);
}
public static void resolvePlaceHolders(ConfigurableEnvironment environment, MapPropertySource propertySource) {
Map<String, Object> source = propertySource.getSource(); Map<String, Object> source = propertySource.getSource();
for (Entry<String, Object> entry : source.entrySet()) { for (Entry<String, Object> entry : source.entrySet()) {
Object value = entry.getValue(); Object value = entry.getValue();
...@@ -116,18 +43,4 @@ public class ConfigUtils { ...@@ -116,18 +43,4 @@ public class ConfigUtils {
} }
} }
private static Map<String, Object> mergeProperties(Map<String, Object> loadedProperties,
Map<String, Object> defaultProperties,
boolean remoteFirst) {
Map<String, Object> mergedProperties;
if (remoteFirst) {
defaultProperties.putAll(loadedProperties);
mergedProperties = defaultProperties;
} else {
loadedProperties.putAll(defaultProperties);
mergedProperties = loadedProperties;
}
return mergedProperties;
}
} }
\ No newline at end of file
package com.schbrain.framework.autoconfigure.apollo.util; package com.schbrain.framework.autoconfigure.apollo.util;
import com.schbrain.framework.autoconfigure.apollo.properties.ApolloProperties; import com.schbrain.framework.autoconfigure.apollo.properties.ApolloProperties;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.boot.DefaultPropertiesPropertySource; import org.springframework.boot.DefaultPropertiesPropertySource;
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
import org.springframework.core.env.*; import org.springframework.core.env.*;
import org.springframework.util.CollectionUtils;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
...@@ -47,7 +46,6 @@ public class PropertySourceOrderUtils { ...@@ -47,7 +46,6 @@ public class PropertySourceOrderUtils {
// Make sure the default configurations always in the end // Make sure the default configurations always in the end
DefaultPropertiesPropertySource.moveToEnd(environment); DefaultPropertiesPropertySource.moveToEnd(environment);
ConfigurationPropertySources.attach(environment);
} }
} }
\ No newline at end of file
org.springframework.boot.env.EnvironmentPostProcessor=\ org.springframework.boot.env.EnvironmentPostProcessor=\
com.schbrain.framework.autoconfigure.apollo.properties.ApolloPropertiesPreparer,\ com.schbrain.framework.autoconfigure.apollo.ApolloConfigurationInitializer,\
com.schbrain.framework.autoconfigure.apollo.SchbrainApolloPropertiesEnvironmentPostProcessor com.schbrain.framework.autoconfigure.apollo.ApolloPropertiesReorderEnvironmentPostProcessor
\ No newline at end of file \ No newline at end of file
com.schbrain.framework.autoconfigure.apollo.SchbrainApolloAutoConfiguration com.schbrain.framework.autoconfigure.apollo.ApolloAutoConfiguration
\ No newline at end of file \ No newline at end of file
...@@ -3,7 +3,7 @@ package com.schbrain.framework.autoconfigure.cache; ...@@ -3,7 +3,7 @@ package com.schbrain.framework.autoconfigure.cache;
import com.schbrain.framework.autoconfigure.cache.properties.CacheProperties; import com.schbrain.framework.autoconfigure.cache.properties.CacheProperties;
import com.schbrain.framework.autoconfigure.cache.provider.CacheProvider; import com.schbrain.framework.autoconfigure.cache.provider.CacheProvider;
import com.schbrain.framework.autoconfigure.cache.provider.CacheProviderDelegate; import com.schbrain.framework.autoconfigure.cache.provider.CacheProviderDelegate;
import com.schbrain.framework.autoconfigure.cache.provider.redis.SchbrainRedisCacheConfiguration; import com.schbrain.framework.autoconfigure.cache.provider.redis.RedisCacheConfiguration;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
...@@ -18,15 +18,14 @@ import org.springframework.core.env.Environment; ...@@ -18,15 +18,14 @@ import org.springframework.core.env.Environment;
* @author zhuyf * @author zhuyf
* @since 2022/7/25 * @since 2022/7/25
*/ */
@Import(RedisCacheConfiguration.class)
@AutoConfiguration(after = RedisAutoConfiguration.class) @AutoConfiguration(after = RedisAutoConfiguration.class)
@EnableConfigurationProperties(CacheProperties.class) @EnableConfigurationProperties(CacheProperties.class)
@Import(SchbrainRedisCacheConfiguration.class) public class CacheAutoConfiguration {
public class SchbrainCacheAutoConfiguration {
@Bean @Bean
@ConditionalOnBean(CacheProvider.class) @ConditionalOnBean(CacheProvider.class)
public CacheProviderDelegate cacheServiceDelegate(CacheProvider cacheProvider, CacheProperties cacheProperties, public CacheProvider cacheProvider(CacheProvider cacheProvider, CacheProperties cacheProperties, Environment environment) {
Environment environment) {
CacheProviderDelegate delegate = new CacheProviderDelegate(cacheProperties, cacheProvider, environment); CacheProviderDelegate delegate = new CacheProviderDelegate(cacheProperties, cacheProvider, environment);
CacheUtils.setCacheProvider(delegate); CacheUtils.setCacheProvider(delegate);
return delegate; return delegate;
......
package com.schbrain.framework.autoconfigure.cache.properties; package com.schbrain.framework.autoconfigure.cache.properties;
import com.schbrain.common.util.support.ConfigurableProperties;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
/** /**
...@@ -8,8 +10,9 @@ import org.springframework.boot.context.properties.ConfigurationProperties; ...@@ -8,8 +10,9 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @since 2022/7/26 * @since 2022/7/26
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@ConfigurationProperties(prefix = "schbrain.cache") @ConfigurationProperties(prefix = "schbrain.cache")
public class CacheProperties { public class CacheProperties extends ConfigurableProperties {
/** /**
* cache prefix * cache prefix
...@@ -24,4 +27,9 @@ public class CacheProperties { ...@@ -24,4 +27,9 @@ public class CacheProperties {
*/ */
private boolean appendPrefix = true; private boolean appendPrefix = true;
@Override
public String getDefaultNamespace() {
return "cache-common";
}
} }
\ No newline at end of file
package com.schbrain.framework.autoconfigure.cache.provider.redis; package com.schbrain.framework.autoconfigure.cache.provider.redis;
import com.schbrain.framework.autoconfigure.cache.provider.CacheProvider; import com.schbrain.framework.autoconfigure.cache.provider.CacheProvider;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.*; import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
...@@ -13,13 +15,14 @@ import org.springframework.data.redis.core.StringRedisTemplate; ...@@ -13,13 +15,14 @@ import org.springframework.data.redis.core.StringRedisTemplate;
* @since 2022/8/7 * @since 2022/8/7
*/ */
@ConditionalOnClass(RedisConnectionFactory.class) @ConditionalOnClass(RedisConnectionFactory.class)
public class SchbrainRedisCacheConfiguration { @EnableConfigurationProperties(RedisProperties.class)
public class RedisCacheConfiguration {
@Bean @Bean
@ConditionalOnBean(RedisConnectionFactory.class) @ConditionalOnBean(RedisConnectionFactory.class)
@ConditionalOnMissingBean(RedisCacheProvider.class) @ConditionalOnMissingBean(RedisCacheProvider.class)
public CacheProvider schbrainRedisCacheProvider(RedisConnectionFactory redisConnectionFactory) { public CacheProvider redisCacheProvider(RedisConnectionFactory redisConnectionFactory, ObjectProvider<StringRedisTemplate> redisTemplate) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(redisConnectionFactory); StringRedisTemplate stringRedisTemplate = redisTemplate.getIfAvailable(() -> new StringRedisTemplate(redisConnectionFactory));
return new RedisCacheProvider(stringRedisTemplate); return new RedisCacheProvider(stringRedisTemplate);
} }
......
package com.schbrain.framework.autoconfigure.cache.provider.redis;
import com.schbrain.common.util.support.ConfigurableProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author liaozan
* @since 2023-04-27
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties extends ConfigurableProperties {
@Override
public String getDefaultNamespace() {
return "redis-common";
}
}
\ No newline at end of file
...@@ -4,6 +4,11 @@ ...@@ -4,6 +4,11 @@
"name": "schbrain.cache", "name": "schbrain.cache",
"type": "com.schbrain.framework.autoconfigure.cache.properties.CacheProperties", "type": "com.schbrain.framework.autoconfigure.cache.properties.CacheProperties",
"sourceType": "com.schbrain.framework.autoconfigure.cache.properties.CacheProperties" "sourceType": "com.schbrain.framework.autoconfigure.cache.properties.CacheProperties"
},
{
"name": "spring.redis",
"type": "com.schbrain.framework.autoconfigure.cache.provider.redis.RedisProperties",
"sourceType": "com.schbrain.framework.autoconfigure.cache.provider.redis.RedisProperties"
} }
], ],
"properties": [ "properties": [
......
com.schbrain.common.util.support.ConfigurableProperties=\
com.schbrain.framework.autoconfigure.cache.properties.CacheProperties,\
com.schbrain.framework.autoconfigure.cache.provider.redis.RedisProperties
\ No newline at end of file
com.schbrain.framework.autoconfigure.cache.SchbrainCacheAutoConfiguration com.schbrain.framework.autoconfigure.cache.CacheAutoConfiguration
\ No newline at end of file \ No newline at end of file
package com.schbrain.framework.autoconfigure.dubbo.listener;
import com.alibaba.fastjson2.JSONFactory;
import com.google.common.collect.Maps;
import com.schbrain.common.util.ApplicationName;
import com.schbrain.framework.autoconfigure.apollo.listener.PropertiesPreparedEvent;
import com.schbrain.framework.autoconfigure.apollo.listener.PropertiesPreparedEventListenerAdapter;
import com.schbrain.framework.autoconfigure.dubbo.properties.DubboProperties;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.spring.ConfigCenterBean;
import org.apache.dubbo.config.spring.util.EnvironmentUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Map;
import java.util.SortedMap;
import static org.apache.dubbo.config.ConfigKeys.DUBBO_SCAN_BASE_PACKAGES;
/**
* @author liaozan
* @since 2023-04-28
*/
public class DubboPropertiesPreparedEventListener extends PropertiesPreparedEventListenerAdapter<DubboProperties> {
public static final String DUBBO_APPLICATION_NAME = "dubbo.application.name";
@Override
protected void onPropertiesPrepared(PropertiesPreparedEvent event, DubboProperties properties) {
ConfigurableEnvironment environment = event.getEnvironment();
Map<String, String> requiredProperties = collectRequiredProperties(environment, event.getApplication());
event.getPropertySource().addProperties(requiredProperties);
injectDubboProperties(environment);
}
private void injectDubboProperties(ConfigurableEnvironment environment) {
JSONFactory.setUseJacksonAnnotation(false);
SortedMap<String, String> dubboProperties = EnvironmentUtils.filterDubboProperties(environment);
ConfigCenterBean configCenterBean = new ConfigCenterBean();
configCenterBean.setExternalConfig(dubboProperties);
DubboBootstrap.getInstance().configCenter(configCenterBean);
}
private Map<String, String> collectRequiredProperties(ConfigurableEnvironment environment, SpringApplication application) {
Map<String, String> dubboRequiredProperties = Maps.newLinkedHashMapWithExpectedSize(2);
dubboRequiredProperties.put(DUBBO_SCAN_BASE_PACKAGES, getBasePackage(application));
dubboRequiredProperties.put(DUBBO_APPLICATION_NAME, ApplicationName.get(environment));
return dubboRequiredProperties;
}
private String getBasePackage(SpringApplication application) {
return application.getMainApplicationClass().getPackage().getName();
}
}
\ No newline at end of file
...@@ -3,12 +3,7 @@ package com.schbrain.framework.autoconfigure.dubbo.properties; ...@@ -3,12 +3,7 @@ package com.schbrain.framework.autoconfigure.dubbo.properties;
import com.schbrain.common.util.support.ConfigurableProperties; import com.schbrain.common.util.support.ConfigurableProperties;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.apache.dubbo.config.spring.util.EnvironmentUtils;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.LinkedHashMap;
import java.util.Map;
/** /**
* used to fetch dubbo.* config from remote * used to fetch dubbo.* config from remote
...@@ -21,27 +16,9 @@ import java.util.Map; ...@@ -21,27 +16,9 @@ import java.util.Map;
@ConfigurationProperties(prefix = "dubbo") @ConfigurationProperties(prefix = "dubbo")
public class DubboProperties extends ConfigurableProperties { public class DubboProperties extends ConfigurableProperties {
private Map<String, String> externalConfigurations;
@Override @Override
public String getDefaultNamespace() { public String getDefaultNamespace() {
return "dubbo-common"; return "dubbo-common";
} }
@Override
@SuppressWarnings("unchecked")
public DubboProperties bindOrCreate(ConfigurableEnvironment environment, boolean afterMerge) {
DubboProperties dubboProperties = super.bindOrCreate(environment, afterMerge);
if (afterMerge) {
Map<String, String> externalConfigurations = new LinkedHashMap<>(EnvironmentUtils.filterDubboProperties(environment));
Map<String, String> configuredProperties = dubboProperties.getExternalConfigurations();
if (configuredProperties == null) {
configuredProperties = new LinkedHashMap<>();
}
externalConfigurations.putAll(configuredProperties);
dubboProperties.setExternalConfigurations(externalConfigurations);
}
return dubboProperties;
}
} }
\ No newline at end of file
package com.schbrain.framework.autoconfigure.dubbo.properties;
import com.alibaba.fastjson2.JSONFactory;
import com.schbrain.common.exception.BaseException;
import com.schbrain.common.util.ApplicationName;
import com.schbrain.framework.autoconfigure.apollo.util.ConfigUtils;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.spring.ConfigCenterBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.LinkedHashMap;
import java.util.Map;
import static org.apache.dubbo.config.ConfigKeys.DUBBO_SCAN_BASE_PACKAGES;
/**
* @author liaozan
* @since 2021/10/10
*/
public class DubboPropertiesPreparer implements EnvironmentPostProcessor, Ordered {
public static final String DUBBO_APPLICATION_NAME = "dubbo.application.name";
public static final Integer DEFAULT_ORDER = Ordered.LOWEST_PRECEDENCE;
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
DubboProperties dubboProperties = ConfigUtils.loadConfig(environment, DubboProperties.class);
addAdditionalProperties(environment, application, dubboProperties);
setUpConfigCenter(dubboProperties);
JSONFactory.setUseJacksonAnnotation(false);
}
@Override
public int getOrder() {
return DEFAULT_ORDER;
}
private void setUpConfigCenter(DubboProperties dubboProperties) {
ConfigCenterBean configCenterConfig = buildConfigCenter(dubboProperties);
DubboBootstrap.getInstance().configCenter(configCenterConfig);
}
private ConfigCenterBean buildConfigCenter(DubboProperties dubboProperties) {
ConfigCenterBean configCenter = new ConfigCenterBean();
configCenter.setExternalConfig(dubboProperties.getExternalConfigurations());
return configCenter;
}
private void addAdditionalProperties(ConfigurableEnvironment environment, SpringApplication application, DubboProperties dubboProperties) {
Map<String, String> configurations = dubboProperties.getExternalConfigurations();
configurations.put(DUBBO_SCAN_BASE_PACKAGES, getBasePackage(application));
if (!configurations.containsKey(DUBBO_APPLICATION_NAME)) {
configurations.put(DUBBO_APPLICATION_NAME, ApplicationName.get(environment));
}
Map<String, Object> properties = new LinkedHashMap<>(dubboProperties.getExternalConfigurations());
ConfigUtils.addToEnvironment(environment, dubboProperties.getName(), properties);
}
private String getBasePackage(SpringApplication application) {
return application.getAllSources()
.stream()
.filter(Class.class::isInstance)
.map(source -> (Class<?>) source)
.map(Class::getPackage)
.map(Package::getName)
.findFirst()
.orElseThrow(() -> new BaseException("should never go here"));
}
}
\ No newline at end of file
...@@ -6,27 +6,6 @@ ...@@ -6,27 +6,6 @@
"sourceType": "com.schbrain.framework.autoconfigure.dubbo.properties.DubboProperties" "sourceType": "com.schbrain.framework.autoconfigure.dubbo.properties.DubboProperties"
} }
], ],
"properties": [ "properties": [],
{
"name": "dubbo.external-configurations",
"type": "java.util.Map<java.lang.String,java.lang.String>",
"sourceType": "com.schbrain.framework.autoconfigure.dubbo.properties.DubboProperties"
},
{
"name": "dubbo.name",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.dubbo.properties.DubboProperties"
},
{
"name": "dubbo.namespace",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.dubbo.properties.DubboProperties"
},
{
"name": "dubbo.prefix",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.dubbo.properties.DubboProperties"
}
],
"hints": [] "hints": []
} }
\ No newline at end of file
org.springframework.boot.env.EnvironmentPostProcessor=com.schbrain.framework.autoconfigure.dubbo.properties.DubboPropertiesPreparer com.schbrain.common.util.support.ConfigurableProperties=\
\ No newline at end of file com.schbrain.framework.autoconfigure.dubbo.properties.DubboProperties
org.springframework.context.ApplicationListener=\
com.schbrain.framework.autoconfigure.dubbo.listener.DubboPropertiesPreparedEventListener
\ No newline at end of file
<?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>
<groupId>com.schbrain.framework</groupId>
<artifactId>starters</artifactId>
<version>${revision}</version>
</parent>
<artifactId>elasticsearch-spring-boot-starter</artifactId>
<dependencies>
<dependency>
<groupId>com.schbrain.framework</groupId>
<artifactId>apollo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.schbrain.framework.autoconfigure.elasticsearch;
import com.schbrain.framework.autoconfigure.elasticsearch.properties.ElasticsearchProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
* @author liaozan
* @since 2023-04-29
*/
@AutoConfiguration
@EnableConfigurationProperties(ElasticsearchProperties.class)
public class ElasticsearchAutoConfiguration {
}
\ No newline at end of file
package com.schbrain.framework.autoconfigure.elasticsearch.properties;
import com.schbrain.common.util.support.ConfigurableProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author liaozan
* @since 2023-04-29
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ConfigurationProperties(prefix = "spring.elasticsearch")
public class ElasticsearchProperties extends ConfigurableProperties {
@Override
public String getDefaultNamespace() {
return "elasticsearch-common";
}
}
\ No newline at end of file
{
"groups": [
{
"name": "spring.elasticsearch",
"type": "com.schbrain.framework.autoconfigure.elasticsearch.properties.ElasticsearchProperties",
"sourceType": "com.schbrain.framework.autoconfigure.elasticsearch.properties.ElasticsearchProperties"
}
],
"properties": [],
"hints": []
}
\ No newline at end of file
com.schbrain.common.util.support.ConfigurableProperties=\
com.schbrain.framework.autoconfigure.elasticsearch.properties.ElasticsearchProperties
\ No newline at end of file
com.schbrain.framework.autoconfigure.elasticsearch.ElasticsearchAutoConfiguration
\ No newline at end of file
<?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>
<groupId>com.schbrain.framework</groupId>
<artifactId>starters</artifactId>
<version>${revision}</version>
</parent>
<artifactId>kafka-spring-boot-starter</artifactId>
<dependencies>
<dependency>
<groupId>com.schbrain.framework</groupId>
<artifactId>apollo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.schbrain.framework.autoconfigure.kafka;
import com.schbrain.framework.autoconfigure.kafka.properties.KafkaProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
* @author liaozan
* @since 2023-04-29
*/
@AutoConfiguration
@EnableConfigurationProperties(KafkaProperties.class)
public class KafkaAutoConfiguration {
}
\ No newline at end of file
package com.schbrain.framework.autoconfigure.kafka.properties;
import com.schbrain.common.util.support.ConfigurableProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author liaozan
* @since 2023-04-29
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ConfigurationProperties(prefix = "spring.kafka")
public class KafkaProperties extends ConfigurableProperties {
@Override
public String getDefaultNamespace() {
return "kafka-common";
}
}
\ No newline at end of file
{
"groups": [
{
"name": "spring.kafka",
"type": "com.schbrain.framework.autoconfigure.kafka.properties.KafkaProperties",
"sourceType": "com.schbrain.framework.autoconfigure.kafka.properties.KafkaProperties"
}
],
"properties": [],
"hints": []
}
\ No newline at end of file
com.schbrain.common.util.support.ConfigurableProperties=\
com.schbrain.framework.autoconfigure.kafka.properties.KafkaProperties
\ No newline at end of file
com.schbrain.framework.autoconfigure.kafka.KafkaAutoConfiguration
\ No newline at end of file
package com.schbrain.framework.autoconfigure.logger; package com.schbrain.framework.autoconfigure.logger;
import com.schbrain.framework.autoconfigure.logger.apollo.DynamicLoggerConfiguration; import com.schbrain.framework.autoconfigure.logger.apollo.DynamicLoggerConfiguration;
import com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties; import com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
...@@ -15,7 +15,7 @@ import org.springframework.core.Ordered; ...@@ -15,7 +15,7 @@ import org.springframework.core.Ordered;
@AutoConfiguration @AutoConfiguration
@Import(DynamicLoggerConfiguration.class) @Import(DynamicLoggerConfiguration.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@EnableConfigurationProperties(LoggingFileProperties.class) @EnableConfigurationProperties(LoggerProperties.class)
public class LoggerAutoConfiguration { public class LoggerAutoConfiguration {
} }
\ No newline at end of file
...@@ -9,10 +9,8 @@ import ch.qos.logback.core.rolling.TimeBasedRollingPolicy; ...@@ -9,10 +9,8 @@ import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import com.schbrain.common.util.*; import com.schbrain.common.util.*;
import com.schbrain.common.util.InetUtils.HostInfo; import com.schbrain.common.util.InetUtils.HostInfo;
import com.schbrain.framework.autoconfigure.apollo.util.ConfigUtils; import com.schbrain.framework.autoconfigure.logger.logstash.EnhancedLogstashEncoder;
import com.schbrain.framework.autoconfigure.logger.logstash.SchbrainLogstashEncoder; import com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties;
import com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.logstash.logback.appender.LogstashTcpSocketAppender; import net.logstash.logback.appender.LogstashTcpSocketAppender;
import net.logstash.logback.encoder.LogstashEncoder; import net.logstash.logback.encoder.LogstashEncoder;
...@@ -20,8 +18,6 @@ import net.logstash.logback.fieldnames.ShortenedFieldNames; ...@@ -20,8 +18,6 @@ import net.logstash.logback.fieldnames.ShortenedFieldNames;
import org.apache.commons.collections4.IteratorUtils; import org.apache.commons.collections4.IteratorUtils;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.cloud.CloudPlatform; import org.springframework.boot.cloud.CloudPlatform;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
...@@ -37,25 +33,23 @@ import java.util.List; ...@@ -37,25 +33,23 @@ import java.util.List;
* @since 2021/12/11 * @since 2021/12/11
*/ */
@Slf4j @Slf4j
@Setter public class LoggerConfigurationInitializer {
public class JsonLoggerInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
/** private final ConfigurableEnvironment environment;
* 暴露 set 方法以便单独启动日志服务时进行配置 private final LoggerProperties properties;
*/ private final String applicationName;
private ConfigurableEnvironment environment;
private LoggingFileProperties loggingFileProperties; public LoggerConfigurationInitializer(ConfigurableEnvironment environment, LoggerProperties properties) {
private String applicationName; this.environment = environment;
this.properties = properties;
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
this.environment = applicationContext.getEnvironment();
this.loggingFileProperties = ConfigUtils.loadConfig(environment, LoggingFileProperties.class);
this.applicationName = ApplicationName.get(environment); this.applicationName = ApplicationName.get(environment);
this.init(); this.init();
} }
public void init() { public void init() {
if (properties == null) {
return;
}
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
for (Logger logger : context.getLoggerList()) { for (Logger logger : context.getLoggerList()) {
registerAppender(logger, context); registerAppender(logger, context);
...@@ -68,18 +62,18 @@ public class JsonLoggerInitializer implements ApplicationContextInitializer<Conf ...@@ -68,18 +62,18 @@ public class JsonLoggerInitializer implements ApplicationContextInitializer<Conf
return; return;
} }
if (loggingFileProperties.isEnableJsonFileOutput()) { if (properties.isEnableJsonFileOutput()) {
Appender<ILoggingEvent> appender = buildFileAppender(context); Appender<ILoggingEvent> appender = buildFileAppender(context);
logger.addAppender(appender); logger.addAppender(appender);
} }
if (loggingFileProperties.isEnableJsonConsoleOutput()) { if (properties.isEnableJsonConsoleOutput()) {
Appender<ILoggingEvent> appender = buildConsoleAppender(context); Appender<ILoggingEvent> appender = buildConsoleAppender(context);
logger.addAppender(appender); logger.addAppender(appender);
} }
if (loggingFileProperties.isEnableJsonLogWriteToLogstash() || EnvUtils.runningOnCloudPlatform(environment)) { if (properties.isEnableJsonLogWriteToLogstash() || EnvUtils.runningOnCloudPlatform(environment)) {
if (!StringUtils.hasText(loggingFileProperties.getLogstashAddress())) { if (!StringUtils.hasText(properties.getLogstashAddress())) {
log.warn("logstash address is unset, will NOT write log to logstash"); log.warn("logstash address is unset, will NOT write log to logstash");
return; return;
} }
...@@ -91,7 +85,7 @@ public class JsonLoggerInitializer implements ApplicationContextInitializer<Conf ...@@ -91,7 +85,7 @@ public class JsonLoggerInitializer implements ApplicationContextInitializer<Conf
private Appender<ILoggingEvent> buildLogstashAppender(LoggerContext context) { private Appender<ILoggingEvent> buildLogstashAppender(LoggerContext context) {
LogstashTcpSocketAppender appender = new LogstashTcpSocketAppender(); LogstashTcpSocketAppender appender = new LogstashTcpSocketAppender();
appender.setContext(context); appender.setContext(context);
appender.addDestination(loggingFileProperties.getLogstashAddress()); appender.addDestination(properties.getLogstashAddress());
appender.setEncoder(createJsonEncoder(context)); appender.setEncoder(createJsonEncoder(context));
appender.start(); appender.start();
return appender; return appender;
...@@ -110,7 +104,7 @@ public class JsonLoggerInitializer implements ApplicationContextInitializer<Conf ...@@ -110,7 +104,7 @@ public class JsonLoggerInitializer implements ApplicationContextInitializer<Conf
} }
private LogstashEncoder createJsonEncoder(LoggerContext loggerContext) { private LogstashEncoder createJsonEncoder(LoggerContext loggerContext) {
LogstashEncoder logstashEncoder = new SchbrainLogstashEncoder(); LogstashEncoder logstashEncoder = new EnhancedLogstashEncoder();
logstashEncoder.setContext(loggerContext); logstashEncoder.setContext(loggerContext);
logstashEncoder.setFieldNames(new ShortenedFieldNames()); logstashEncoder.setFieldNames(new ShortenedFieldNames());
logstashEncoder.setShortenedLoggerNameLength(40); logstashEncoder.setShortenedLoggerNameLength(40);
...@@ -139,12 +133,12 @@ public class JsonLoggerInitializer implements ApplicationContextInitializer<Conf ...@@ -139,12 +133,12 @@ public class JsonLoggerInitializer implements ApplicationContextInitializer<Conf
} }
private String getPathLocation(String path) { private String getPathLocation(String path) {
return Paths.get(loggingFileProperties.getLogPath(), path).toString(); return Paths.get(properties.getLogPath(), path).toString();
} }
private TimeBasedRollingPolicy<ILoggingEvent> createRollingPolicy(Context context, FileAppender<ILoggingEvent> appender) { private TimeBasedRollingPolicy<ILoggingEvent> createRollingPolicy(Context context, FileAppender<ILoggingEvent> appender) {
TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new TimeBasedRollingPolicy<>(); TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new TimeBasedRollingPolicy<>();
rollingPolicy.setMaxHistory(loggingFileProperties.getMaxHistory()); rollingPolicy.setMaxHistory(properties.getMaxHistory());
rollingPolicy.setFileNamePattern(getPathLocation("json/json-%d{yyyy-MM-dd}.log")); rollingPolicy.setFileNamePattern(getPathLocation("json/json-%d{yyyy-MM-dd}.log"));
rollingPolicy.setContext(context); rollingPolicy.setContext(context);
rollingPolicy.setParent(appender); rollingPolicy.setParent(appender);
......
package com.schbrain.framework.autoconfigure.logger.apollo; package com.schbrain.framework.autoconfigure.logger.apollo;
import com.ctrip.framework.apollo.*; import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat; import com.ctrip.framework.apollo.ConfigService;
import com.schbrain.framework.autoconfigure.apollo.util.ConfigUtils;
import com.schbrain.framework.autoconfigure.logger.apollo.listener.LoggingConfigFileChangeListener;
import com.schbrain.framework.autoconfigure.logger.apollo.listener.LoggingLevelChangeListener; import com.schbrain.framework.autoconfigure.logger.apollo.listener.LoggingLevelChangeListener;
import com.schbrain.framework.autoconfigure.logger.properties.LoggingNamespaceProperties; import com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.logging.LoggingSystem; import org.springframework.boot.logging.LoggingSystem;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
...@@ -19,47 +15,14 @@ import org.springframework.util.StringUtils; ...@@ -19,47 +15,14 @@ import org.springframework.util.StringUtils;
* @since 2021/11/19 * @since 2021/11/19
**/ **/
@Slf4j @Slf4j
@EnableConfigurationProperties(LoggingNamespaceProperties.class)
public class DynamicLoggerConfiguration { public class DynamicLoggerConfiguration {
private final ConfigurableEnvironment environment; public DynamicLoggerConfiguration(LoggingSystem loggingSystem, LoggerProperties loggerProperties) {
private final LoggingSystem loggingSystem; this.listenToLoggingLevelChange(loggingSystem, loggerProperties);
private final LoggingNamespaceProperties loggerProperties;
public DynamicLoggerConfiguration(ConfigurableEnvironment environment, LoggingSystem loggingSystem,
LoggingNamespaceProperties loggerProperties) {
this.environment = environment;
this.loggingSystem = loggingSystem;
this.loggerProperties = loggerProperties;
this.init();
}
private void init() {
if (ConfigUtils.isApolloDisabled()) {
return;
}
listenToLoggingLevelChange();
listenToLoggingConfigFileChange();
}
private void listenToLoggingConfigFileChange() {
String loggerConfigFileNamespace = loggerProperties.getLoggerConfigFile();
if (!StringUtils.hasText(loggerConfigFileNamespace)) {
log.debug("logger config file reload is disabled");
return;
}
log.debug("init logger config file listener, config file namespace: {}", loggerConfigFileNamespace);
ConfigFile loggingConfiguration = ConfigService.getConfigFile(loggerConfigFileNamespace, ConfigFileFormat.XML);
if (!loggingConfiguration.hasContent()) {
return;
}
loggingConfiguration.addChangeListener(new LoggingConfigFileChangeListener(loggingSystem, environment, loggerConfigFileNamespace));
} }
private void listenToLoggingLevelChange() { private void listenToLoggingLevelChange(LoggingSystem loggingSystem, LoggerProperties loggerProperties) {
String loggerNamespace = loggerProperties.getLogger(); String loggerNamespace = loggerProperties.getDefaultNamespace();
if (!StringUtils.hasText(loggerNamespace)) { if (!StringUtils.hasText(loggerNamespace)) {
log.debug("logger level reload is disabled"); log.debug("logger level reload is disabled");
return; return;
......
package com.schbrain.framework.autoconfigure.logger.apollo.listener;
import cn.hutool.extra.spring.SpringUtil;
import com.ctrip.framework.apollo.ConfigFileChangeListener;
import com.ctrip.framework.apollo.model.ConfigFileChangeEvent;
import com.schbrain.framework.autoconfigure.logger.JsonLoggerInitializer;
import com.schbrain.framework.autoconfigure.logger.util.LoggerUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.logging.*;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.StringUtils;
import java.util.List;
/**
* @author liaozan
* @since 2021/11/8
*/
@Slf4j
public class LoggingConfigFileChangeListener implements ConfigFileChangeListener {
private final LoggingSystem loggingSystem;
private final ConfigurableEnvironment environment;
private final String loggerFileName;
public LoggingConfigFileChangeListener(LoggingSystem loggingSystem, ConfigurableEnvironment environment, String loggerFileName) {
this.loggingSystem = loggingSystem;
this.environment = environment;
this.loggerFileName = loggerFileName;
}
@Override
public void onChange(ConfigFileChangeEvent changeEvent) {
String content = changeEvent.getNewValue();
if (!StringUtils.hasText(content)) {
log.warn("Empty logging configuration, reInitialize loggingSystem is disabled");
return;
}
String configurationLocation = LoggerUtils.storeConfiguration(loggerFileName, content);
if (configurationLocation == null) {
return;
}
reinitialize(configurationLocation);
log.debug("ReInitialize loggingSystem, configFile location: {}", configurationLocation);
}
private void reinitialize(String configLocation) {
List<LoggerConfiguration> configurations = loggingSystem.getLoggerConfigurations();
loggingSystem.cleanUp();
loggingSystem.initialize(new LoggingInitializationContext(environment), configLocation, null);
configurations.forEach(configuration -> loggingSystem.setLogLevel(configuration.getName(), configuration.getConfiguredLevel()));
// reInitialize json logger
new JsonLoggerInitializer().initialize(SpringUtil.getBean(ConfigurableApplicationContext.class));
}
}
\ No newline at end of file
package com.schbrain.framework.autoconfigure.logger.listener;
import cn.hutool.system.SystemUtil;
import com.ctrip.framework.apollo.ConfigFile;
import com.ctrip.framework.apollo.ConfigService;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.google.common.collect.Maps;
import com.schbrain.common.util.InetUtils;
import com.schbrain.common.util.InetUtils.HostInfo;
import com.schbrain.framework.autoconfigure.apollo.listener.PropertiesPreparedEvent;
import com.schbrain.framework.autoconfigure.apollo.listener.PropertiesPreparedEventListenerAdapter;
import com.schbrain.framework.autoconfigure.logger.LoggerConfigurationInitializer;
import com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.nio.file.*;
import java.util.Map;
import static org.springframework.boot.context.logging.LoggingApplicationListener.CONFIG_PROPERTY;
/**
* @author liaozan
* @since 2023-04-28
*/
@Slf4j
public class LoggerPropertiesPreparedEventListener extends PropertiesPreparedEventListenerAdapter<LoggerProperties> {
@Override
protected void onPropertiesPrepared(PropertiesPreparedEvent event, LoggerProperties properties) {
ConfigurableEnvironment environment = event.getEnvironment();
Map<String, String> hostInfoProperties = buildHostInfoProperties();
event.getPropertySource().addProperties(hostInfoProperties);
configLoggingFileLocation(environment);
new LoggerConfigurationInitializer(environment, properties).init();
}
private Map<String, String> buildHostInfoProperties() {
HostInfo hostInfo = InetUtils.findFirstNonLoopBackHostInfo();
Map<String, String> properties = Maps.newHashMapWithExpectedSize(2);
properties.put("application.hostname", hostInfo.getHostname());
properties.put("application.ipAddress", hostInfo.getIpAddress());
return properties;
}
/**
* Add {@link org.springframework.boot.context.logging.LoggingApplicationListener#CONFIG_PROPERTY} property to SystemProperty
*
* @see org.springframework.boot.context.logging.LoggingApplicationListener#initializeSystem(ConfigurableEnvironment, org.springframework.boot.logging.LoggingSystem, org.springframework.boot.logging.LogFile)
*/
@SuppressWarnings("JavadocReference")
private void configLoggingFileLocation(ConfigurableEnvironment environment) {
if (environment.containsProperty(CONFIG_PROPERTY)) {
return;
}
ConfigFile loggingConfiguration = ConfigService.getConfigFile("logback-spring", ConfigFileFormat.XML);
String content = loggingConfiguration.getContent();
if (!StringUtils.hasText(content)) {
log.warn("empty logging configuration, reinitialize loggingSystem is disabled");
return;
}
String loggerConfigurationLocation = null;
String tempDir = SystemUtil.getUserInfo().getTempDir();
Path storeLocation = Paths.get(tempDir, "logback-spring.xml");
try {
loggerConfigurationLocation = Files.writeString(storeLocation, content).toString();
} catch (IOException e) {
log.warn("failed to write logging file, will not behave as expected", e);
}
if (loggerConfigurationLocation == null) {
return;
}
System.setProperty(CONFIG_PROPERTY, loggerConfigurationLocation);
log.debug(String.format("%s is set to %s", CONFIG_PROPERTY, loggerConfigurationLocation));
}
}
\ No newline at end of file
...@@ -8,11 +8,11 @@ import net.logstash.logback.encoder.LogstashEncoder; ...@@ -8,11 +8,11 @@ import net.logstash.logback.encoder.LogstashEncoder;
* @author liaozan * @author liaozan
* @since 2022/1/4 * @since 2022/1/4
*/ */
public class SchbrainLogstashEncoder extends LogstashEncoder { public class EnhancedLogstashEncoder extends LogstashEncoder {
@Override @Override
protected AbstractCompositeJsonFormatter<ILoggingEvent> createFormatter() { protected AbstractCompositeJsonFormatter<ILoggingEvent> createFormatter() {
return new SchbrainLogstashFormatter(this); return new EnhancedLogstashFormatter(this);
} }
} }
\ No newline at end of file
...@@ -15,9 +15,9 @@ import java.util.List; ...@@ -15,9 +15,9 @@ import java.util.List;
* @author liaozan * @author liaozan
* @since 2022/1/4 * @since 2022/1/4
*/ */
public class SchbrainLogstashFormatter extends LogstashFormatter { public class EnhancedLogstashFormatter extends LogstashFormatter {
public SchbrainLogstashFormatter(ContextAware declaredOrigin) { public EnhancedLogstashFormatter(ContextAware declaredOrigin) {
super(declaredOrigin); super(declaredOrigin);
configureProviders(); configureProviders();
} }
......
...@@ -4,6 +4,7 @@ import com.schbrain.common.util.support.ConfigurableProperties; ...@@ -4,6 +4,7 @@ import com.schbrain.common.util.support.ConfigurableProperties;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.PriorityOrdered;
import java.time.Duration; import java.time.Duration;
...@@ -14,7 +15,7 @@ import java.time.Duration; ...@@ -14,7 +15,7 @@ import java.time.Duration;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ConfigurationProperties(prefix = "schbrain.logging.file") @ConfigurationProperties(prefix = "schbrain.logging.file")
public class LoggingFileProperties extends ConfigurableProperties { public class LoggerProperties extends ConfigurableProperties implements PriorityOrdered {
public static final String DEFAULT_LOG_PATH = "/data/logs"; public static final String DEFAULT_LOG_PATH = "/data/logs";
...@@ -30,4 +31,14 @@ public class LoggingFileProperties extends ConfigurableProperties { ...@@ -30,4 +31,14 @@ public class LoggingFileProperties extends ConfigurableProperties {
private int maxHistory = (int) Duration.ofDays(30).toDays(); private int maxHistory = (int) Duration.ofDays(30).toDays();
@Override
public String getDefaultNamespace() {
return "logger-common";
}
@Override
public int getOrder() {
return HIGHEST_PRECEDENCE;
}
} }
\ No newline at end of file
package com.schbrain.framework.autoconfigure.logger.properties;
import com.google.common.collect.Maps;
import com.schbrain.common.util.InetUtils;
import com.schbrain.common.util.InetUtils.HostInfo;
import com.schbrain.framework.autoconfigure.apollo.properties.ApolloPropertiesPreparer;
import com.schbrain.framework.autoconfigure.apollo.util.ConfigUtils;
import com.schbrain.framework.autoconfigure.logger.util.LoggerUtils;
import com.schbrain.framework.support.spring.EnvironmentPostProcessorAdapter;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.logging.LoggingApplicationListener;
import org.springframework.boot.logging.*;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Map;
import static com.schbrain.framework.autoconfigure.logger.util.LoggerUtils.getLoggerConfigurationLocation;
import static org.springframework.boot.context.logging.LoggingApplicationListener.CONFIG_PROPERTY;
/**
* @author liaozan
* @since 2021/11/19
*/
public class LoggerPropertiesPreparer extends EnvironmentPostProcessorAdapter implements Ordered {
public LoggerPropertiesPreparer(DeferredLogFactory factory, ConfigurableBootstrapContext bootstrapContext) {
super(factory, bootstrapContext);
}
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
LoggerUtils.setLogFactory(getDeferredLogFactory());
bindLoggingProperties(environment);
bindHostInfoProperty(environment);
earlyLoadLoggingConfig(environment);
}
@Override
public int getOrder() {
// Configure after the apollo property is initialize
return ApolloPropertiesPreparer.ORDER + 1;
}
@Override
public void onBootstrapContextClosed(ConfigurableApplicationContext applicationContext) {
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
if (!beanFactory.containsSingleton(HostInfo.NAME)) {
HostInfo hostInfo = InetUtils.findFirstNonLoopBackHostInfo();
beanFactory.registerSingleton(HostInfo.NAME, hostInfo);
}
}
private void bindHostInfoProperty(ConfigurableEnvironment environment) {
HostInfo hostInfo = InetUtils.findFirstNonLoopBackHostInfo();
Map<String, Object> source = Maps.newHashMapWithExpectedSize(2);
source.put("application.hostname", hostInfo.getHostname());
source.put("application.ipAddress", hostInfo.getIpAddress());
ConfigUtils.addToEnvironment(environment, HostInfo.NAME, source);
}
/**
* @see LoggingApplicationListener#setLogLevels(LoggingSystem, ConfigurableEnvironment)
*/
@SuppressWarnings("JavadocReference")
private void earlyLoadLoggingConfig(ConfigurableEnvironment environment) {
LoggingNamespaceProperties properties = ConfigUtils.loadConfig(environment, LoggingNamespaceProperties.class);
// load logging level properties
Map<String, Object> loggingLevelProperties = ConfigUtils.loadConfig(properties.getLogger());
ConfigUtils.addToEnvironment(environment, "loggingLevelProperties", loggingLevelProperties);
// load logging file properties
ConfigUtils.loadConfig(environment, LoggingFileProperties.class);
}
/**
* Add {@link LoggingApplicationListener#CONFIG_PROPERTY} property to SystemProperty
*
* @see LoggingApplicationListener#initializeSystem(ConfigurableEnvironment, LoggingSystem, LogFile)
*/
@SuppressWarnings("JavadocReference")
private void bindLoggingProperties(ConfigurableEnvironment environment) {
if (environment.containsProperty(CONFIG_PROPERTY)) {
return;
}
String loggerConfigurationLocation = getLoggerConfigurationLocation(environment);
if (loggerConfigurationLocation == null) {
return;
}
System.setProperty(CONFIG_PROPERTY, loggerConfigurationLocation);
getLog().debug(String.format("%s is set to %s", CONFIG_PROPERTY, loggerConfigurationLocation));
}
}
\ No newline at end of file
package com.schbrain.framework.autoconfigure.logger.util;
import cn.hutool.system.SystemUtil;
import com.ctrip.framework.apollo.ConfigFile;
import com.ctrip.framework.apollo.ConfigService;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.schbrain.framework.autoconfigure.apollo.util.ConfigUtils;
import com.schbrain.framework.autoconfigure.logger.properties.LoggingNamespaceProperties;
import org.apache.commons.logging.Log;
import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.StringUtils;
import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
/**
* @author liaozan
* @since 2021/11/15
*/
public class LoggerUtils {
private static Log LOGGER;
public static void setLogFactory(DeferredLogFactory deferredLog) {
LOGGER = deferredLog.getLog(LoggerUtils.class);
}
@Nullable
public static String getLoggerConfigurationLocation(ConfigurableEnvironment environment) {
if (ConfigUtils.isApolloDisabled()) {
return null;
}
LoggingNamespaceProperties properties = ConfigUtils.loadConfig(environment, LoggingNamespaceProperties.class);
String namespace = properties.getLoggerConfigFile();
ConfigFile loggingConfiguration = ConfigService.getConfigFile(namespace, ConfigFileFormat.XML);
String content = loggingConfiguration.getContent();
if (!StringUtils.hasText(content)) {
LOGGER.warn("empty logging configuration, reinitialize loggingSystem is disabled");
return null;
}
return storeConfiguration(namespace, content);
}
@Nullable
public static String storeConfiguration(String fileName, String content) {
String tempDir = SystemUtil.getUserInfo().getTempDir();
Path storeLocation = Paths.get(tempDir, fileName + ".xml");
try {
return Files.write(storeLocation, content.getBytes(StandardCharsets.UTF_8)).toString();
} catch (IOException e) {
LOGGER.warn("failed to write logging file, will not behave as expected", e);
return null;
}
}
}
\ No newline at end of file
...@@ -2,92 +2,45 @@ ...@@ -2,92 +2,45 @@
"groups": [ "groups": [
{ {
"name": "schbrain.logging.file", "name": "schbrain.logging.file",
"type": "com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties", "type": "com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties" "sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties"
},
{
"name": "schbrain.logging.namespace",
"type": "com.schbrain.framework.autoconfigure.logger.properties.LoggingNamespaceProperties",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingNamespaceProperties"
} }
], ],
"properties": [ "properties": [
{ {
"name": "schbrain.logging.file.enable-json-console-output", "name": "schbrain.logging.file.enable-json-console-output",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties", "sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties",
"defaultValue": false "defaultValue": false
}, },
{ {
"name": "schbrain.logging.file.enable-json-file-output", "name": "schbrain.logging.file.enable-json-file-output",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties", "sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties",
"defaultValue": false "defaultValue": false
}, },
{ {
"name": "schbrain.logging.file.enable-json-log-write-to-logstash", "name": "schbrain.logging.file.enable-json-log-write-to-logstash",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties", "sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties",
"defaultValue": false "defaultValue": false
}, },
{ {
"name": "schbrain.logging.file.log-path", "name": "schbrain.logging.file.log-path",
"type": "java.lang.String", "type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties", "sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties",
"defaultValue": "\/data\/logs" "defaultValue": "\/data\/logs"
}, },
{ {
"name": "schbrain.logging.file.logstash-address", "name": "schbrain.logging.file.logstash-address",
"type": "java.lang.String", "type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties" "sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties"
}, },
{ {
"name": "schbrain.logging.file.max-history", "name": "schbrain.logging.file.max-history",
"type": "java.lang.Integer", "type": "java.lang.Integer",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties", "sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties",
"defaultValue": 0 "defaultValue": 0
},
{
"name": "schbrain.logging.file.name",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties"
},
{
"name": "schbrain.logging.file.namespace",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties"
},
{
"name": "schbrain.logging.file.prefix",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties"
},
{
"name": "schbrain.logging.namespace.logger",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingNamespaceProperties",
"defaultValue": "logger-common"
},
{
"name": "schbrain.logging.namespace.logger-config-file",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingNamespaceProperties",
"defaultValue": "logback-spring"
},
{
"name": "schbrain.logging.namespace.name",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingNamespaceProperties"
},
{
"name": "schbrain.logging.namespace.namespace",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingNamespaceProperties"
},
{
"name": "schbrain.logging.namespace.prefix",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.logger.properties.LoggingNamespaceProperties"
} }
], ],
"hints": [] "hints": []
......
org.springframework.context.ApplicationContextInitializer=\ org.springframework.context.ApplicationContextInitializer=\
com.schbrain.framework.autoconfigure.logger.JsonLoggerInitializer,\
com.schbrain.framework.autoconfigure.logger.logback.LogbackTraceIdConfiguration com.schbrain.framework.autoconfigure.logger.logback.LogbackTraceIdConfiguration
org.springframework.boot.env.EnvironmentPostProcessor=com.schbrain.framework.autoconfigure.logger.properties.LoggerPropertiesPreparer org.springframework.context.ApplicationListener=\
\ No newline at end of file com.schbrain.framework.autoconfigure.logger.listener.LoggerPropertiesPreparedEventListener
com.schbrain.common.util.support.ConfigurableProperties=\
com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties
\ No newline at end of file
...@@ -14,8 +14,7 @@ import com.schbrain.framework.autoconfigure.mybatis.datasource.customizer.DataSo ...@@ -14,8 +14,7 @@ import com.schbrain.framework.autoconfigure.mybatis.datasource.customizer.DataSo
import com.schbrain.framework.autoconfigure.mybatis.datasource.customizer.DefaultDataSourceCustomizer; import com.schbrain.framework.autoconfigure.mybatis.datasource.customizer.DefaultDataSourceCustomizer;
import com.schbrain.framework.autoconfigure.mybatis.datasource.extractor.*; import com.schbrain.framework.autoconfigure.mybatis.datasource.extractor.*;
import com.schbrain.framework.autoconfigure.mybatis.listener.TableConstraintCheckerBean; import com.schbrain.framework.autoconfigure.mybatis.listener.TableConstraintCheckerBean;
import com.schbrain.framework.autoconfigure.mybatis.properties.DataSourceConnectionProperties; import com.schbrain.framework.autoconfigure.mybatis.properties.*;
import com.schbrain.framework.autoconfigure.mybatis.properties.MybatisProperties;
import com.schbrain.framework.autoconfigure.mybatis.sql.injector.DefaultMethodSqlInjector; import com.schbrain.framework.autoconfigure.mybatis.sql.injector.DefaultMethodSqlInjector;
import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
...@@ -33,7 +32,7 @@ import java.util.List; ...@@ -33,7 +32,7 @@ import java.util.List;
* @since 2021/10/14 * @since 2021/10/14
*/ */
@AutoConfiguration(before = MybatisPlusAutoConfiguration.class) @AutoConfiguration(before = MybatisPlusAutoConfiguration.class)
@EnableConfigurationProperties({MybatisProperties.class, DataSourceConnectionProperties.class}) @EnableConfigurationProperties({DataSourceProperties.class, MybatisProperties.class, DataSourceConnectionProperties.class})
@Import({HikariDataSourcePropertiesExtractor.class, DruidDataSourcePropertiesExtractor.class}) @Import({HikariDataSourcePropertiesExtractor.class, DruidDataSourcePropertiesExtractor.class})
@Role(BeanDefinition.ROLE_INFRASTRUCTURE) @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class MybatisAutoConfiguration { public class MybatisAutoConfiguration {
......
package com.schbrain.framework.autoconfigure.logger.properties; package com.schbrain.framework.autoconfigure.mybatis.properties;
import com.schbrain.common.util.support.ConfigurableProperties; import com.schbrain.common.util.support.ConfigurableProperties;
import lombok.Data; import lombok.Data;
...@@ -7,15 +7,16 @@ import org.springframework.boot.context.properties.ConfigurationProperties; ...@@ -7,15 +7,16 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
/** /**
* @author liaozan * @author liaozan
* @since 2021/11/24 * @since 2023-04-27
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ConfigurationProperties(prefix = "schbrain.logging.namespace") @ConfigurationProperties(prefix = "spring.datasource")
public class LoggingNamespaceProperties extends ConfigurableProperties { public class DataSourceProperties extends ConfigurableProperties {
private String logger = "logger-common"; @Override
public String getDefaultNamespace() {
private String loggerConfigFile = "logback-spring"; return "jdbc-common";
}
} }
\ No newline at end of file
...@@ -9,6 +9,11 @@ ...@@ -9,6 +9,11 @@
"name": "schbrain.mybatis", "name": "schbrain.mybatis",
"type": "com.schbrain.framework.autoconfigure.mybatis.properties.MybatisProperties", "type": "com.schbrain.framework.autoconfigure.mybatis.properties.MybatisProperties",
"sourceType": "com.schbrain.framework.autoconfigure.mybatis.properties.MybatisProperties" "sourceType": "com.schbrain.framework.autoconfigure.mybatis.properties.MybatisProperties"
},
{
"name": "spring.datasource",
"type": "com.schbrain.framework.autoconfigure.mybatis.properties.DataSourceProperties",
"sourceType": "com.schbrain.framework.autoconfigure.mybatis.properties.DataSourceProperties"
} }
], ],
"properties": [ "properties": [
...@@ -92,21 +97,6 @@ ...@@ -92,21 +97,6 @@
"description": "是否开启表约束检查", "description": "是否开启表约束检查",
"sourceType": "com.schbrain.framework.autoconfigure.mybatis.properties.MybatisProperties", "sourceType": "com.schbrain.framework.autoconfigure.mybatis.properties.MybatisProperties",
"defaultValue": true "defaultValue": true
},
{
"name": "schbrain.mybatis.name",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.mybatis.properties.MybatisProperties"
},
{
"name": "schbrain.mybatis.namespace",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.mybatis.properties.MybatisProperties"
},
{
"name": "schbrain.mybatis.prefix",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.mybatis.properties.MybatisProperties"
} }
], ],
"hints": [] "hints": []
......
org.springframework.boot.diagnostics.FailureAnalyzer=com.schbrain.framework.autoconfigure.mybatis.constraint.TableConstraintCheckFailureAnalyzer org.springframework.boot.diagnostics.FailureAnalyzer=\
\ No newline at end of file com.schbrain.framework.autoconfigure.mybatis.constraint.TableConstraintCheckFailureAnalyzer
com.schbrain.common.util.support.ConfigurableProperties=\
com.schbrain.framework.autoconfigure.mybatis.properties.MybatisProperties,\
com.schbrain.framework.autoconfigure.mybatis.properties.DataSourceProperties
\ No newline at end of file
package com.schbrain.framework.autoconfigure.oss; package com.schbrain.framework.autoconfigure.oss;
import com.schbrain.framework.autoconfigure.apollo.util.ConfigUtils;
import com.schbrain.framework.autoconfigure.oss.properties.OssProperties; import com.schbrain.framework.autoconfigure.oss.properties.OssProperties;
import com.schbrain.framework.autoconfigure.oss.util.OssUtils; import com.schbrain.framework.autoconfigure.oss.util.OssUtils;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
...@@ -16,13 +15,8 @@ import org.springframework.core.env.ConfigurableEnvironment; ...@@ -16,13 +15,8 @@ import org.springframework.core.env.ConfigurableEnvironment;
@EnableConfigurationProperties(OssProperties.class) @EnableConfigurationProperties(OssProperties.class)
public class OssAutoConfiguration { public class OssAutoConfiguration {
public OssAutoConfiguration(ConfigurableApplicationContext applicationContext) { public OssAutoConfiguration(ConfigurableApplicationContext applicationContext, OssProperties ossProperties) {
initialize(applicationContext);
}
private void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment(); ConfigurableEnvironment environment = applicationContext.getEnvironment();
OssProperties ossProperties = ConfigUtils.loadConfig(environment, OssProperties.class);
OssUtils.initialize(environment, ossProperties); OssUtils.initialize(environment, ossProperties);
} }
......
...@@ -38,21 +38,6 @@ ...@@ -38,21 +38,6 @@
"type": "java.lang.String", "type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.oss.properties.OssProperties" "sourceType": "com.schbrain.framework.autoconfigure.oss.properties.OssProperties"
}, },
{
"name": "schbrain.oss.name",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.oss.properties.OssProperties"
},
{
"name": "schbrain.oss.namespace",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.oss.properties.OssProperties"
},
{
"name": "schbrain.oss.prefix",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.oss.properties.OssProperties"
},
{ {
"name": "schbrain.oss.secret-access-key", "name": "schbrain.oss.secret-access-key",
"type": "java.lang.String", "type": "java.lang.String",
......
com.schbrain.common.util.support.ConfigurableProperties=\
com.schbrain.framework.autoconfigure.oss.properties.OssProperties
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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"> 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> <modelVersion>4.0.0</modelVersion>
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
<module>apollo-spring-boot-starter</module> <module>apollo-spring-boot-starter</module>
<module>cache-spring-boot-starter</module> <module>cache-spring-boot-starter</module>
<module>dubbo-spring-boot-starter</module> <module>dubbo-spring-boot-starter</module>
<module>elasticsearch-spring-boot-starter</module>
<module>kafka-spring-boot-starter</module>
<module>logger-spring-boot-starter</module> <module>logger-spring-boot-starter</module>
<module>mybatis-spring-boot-starter</module> <module>mybatis-spring-boot-starter</module>
<module>oss-spring-boot-starter</module> <module>oss-spring-boot-starter</module>
......
package com.schbrain.framework.autoconfigure.xxl; package com.schbrain.framework.autoconfigure.xxl;
import com.schbrain.common.util.ApplicationName; import com.schbrain.common.util.ApplicationName;
import com.schbrain.framework.autoconfigure.apollo.util.ConfigUtils; import com.schbrain.framework.autoconfigure.logger.properties.LoggerProperties;
import com.schbrain.framework.autoconfigure.logger.properties.LoggingFileProperties;
import com.schbrain.framework.autoconfigure.xxl.condition.XxlJobShouldAvailableCondition; import com.schbrain.framework.autoconfigure.xxl.condition.XxlJobShouldAvailableCondition;
import com.schbrain.framework.autoconfigure.xxl.properties.XxlJobProperties; import com.schbrain.framework.autoconfigure.xxl.properties.XxlJobProperties;
import com.xxl.job.core.executor.XxlJobExecutor; import com.xxl.job.core.executor.XxlJobExecutor;
...@@ -26,9 +25,9 @@ public class XxlJobAutoConfiguration { ...@@ -26,9 +25,9 @@ public class XxlJobAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(XxlJobExecutor.class) @ConditionalOnMissingBean(XxlJobExecutor.class)
public SchbrainXxlJobExecutor schbrainXxlJobSpringExecutor(ConfigurableEnvironment environment) { public SchbrainXxlJobExecutor schbrainXxlJobSpringExecutor(ConfigurableEnvironment environment,
XxlJobProperties xxlJobProperties = ConfigUtils.loadConfig(environment, XxlJobProperties.class); XxlJobProperties xxlJobProperties,
LoggingFileProperties loggingProperties = ConfigUtils.loadConfig(environment, LoggingFileProperties.class); LoggerProperties loggingProperties) {
String applicationName = ApplicationName.get(environment); String applicationName = ApplicationName.get(environment);
SchbrainXxlJobExecutor executor = new SchbrainXxlJobExecutor(); SchbrainXxlJobExecutor executor = new SchbrainXxlJobExecutor();
executor.setAdminAddresses(xxlJobProperties.getAdminAddresses()); executor.setAdminAddresses(xxlJobProperties.getAdminAddresses());
......
...@@ -28,27 +28,12 @@ ...@@ -28,27 +28,12 @@
"sourceType": "com.schbrain.framework.autoconfigure.xxl.properties.XxlJobProperties", "sourceType": "com.schbrain.framework.autoconfigure.xxl.properties.XxlJobProperties",
"defaultValue": 7 "defaultValue": 7
}, },
{
"name": "schbrain.xxl.name",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.xxl.properties.XxlJobProperties"
},
{
"name": "schbrain.xxl.namespace",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.xxl.properties.XxlJobProperties"
},
{ {
"name": "schbrain.xxl.port", "name": "schbrain.xxl.port",
"type": "java.lang.Integer", "type": "java.lang.Integer",
"sourceType": "com.schbrain.framework.autoconfigure.xxl.properties.XxlJobProperties", "sourceType": "com.schbrain.framework.autoconfigure.xxl.properties.XxlJobProperties",
"defaultValue": -1 "defaultValue": -1
}, },
{
"name": "schbrain.xxl.prefix",
"type": "java.lang.String",
"sourceType": "com.schbrain.framework.autoconfigure.xxl.properties.XxlJobProperties"
},
{ {
"name": "schbrain.xxl.register", "name": "schbrain.xxl.register",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
......
com.schbrain.common.util.support.ConfigurableProperties=\
com.schbrain.framework.autoconfigure.xxl.properties.XxlJobProperties
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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"> 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> <modelVersion>4.0.0</modelVersion>
......
package com.schbrain.framework.support.spring;
import cn.hutool.core.lang.Singleton;
import org.springframework.boot.BootstrapContextClosedEvent;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import java.util.ArrayList;
import java.util.List;
/**
* @author liaozan
* @since 2021/11/22
*/
public class BootstrapContextListenerComposite implements ApplicationListener<BootstrapContextClosedEvent> {
private final List<EnvironmentPostProcessorAdapter> adapters = new ArrayList<>();
public static BootstrapContextListenerComposite getInstance() {
return Singleton.get(BootstrapContextListenerComposite.class);
}
public void addListener(EnvironmentPostProcessorAdapter adapter) {
if (adapters.contains(adapter)) {
return;
}
adapters.add(adapter);
}
@Override
public void onApplicationEvent(BootstrapContextClosedEvent event) {
if (adapters.isEmpty()) {
return;
}
AnnotationAwareOrderComparator.sort(adapters);
ConfigurableBootstrapContext bootstrapContext = (ConfigurableBootstrapContext) event.getBootstrapContext();
ConfigurableApplicationContext applicationContext = event.getApplicationContext();
for (EnvironmentPostProcessorAdapter adapter : adapters) {
adapter.onBootstrapContextClosed(bootstrapContext, applicationContext);
}
}
}
...@@ -5,38 +5,22 @@ import org.apache.commons.logging.Log; ...@@ -5,38 +5,22 @@ import org.apache.commons.logging.Log;
import org.springframework.boot.ConfigurableBootstrapContext; import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.logging.DeferredLogFactory; import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.context.ConfigurableApplicationContext;
/** /**
* @author liaozan * @author liaozan
* @since 2021/11/22 * @since 2021/11/22
*/ */
@Getter @Getter
public abstract class EnvironmentPostProcessorAdapter implements EnvironmentPostProcessor { public abstract class EnvironmentPostProcessorLoggerAwareAdapter implements EnvironmentPostProcessor {
private final Log log; private final Log log;
private final DeferredLogFactory deferredLogFactory; private final DeferredLogFactory deferredLogFactory;
private final ConfigurableBootstrapContext bootstrapContext; private final ConfigurableBootstrapContext bootstrapContext;
public EnvironmentPostProcessorAdapter(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext) { public EnvironmentPostProcessorLoggerAwareAdapter(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext) {
this.log = logFactory.getLog(getClass()); this.log = logFactory.getLog(getClass());
this.bootstrapContext = bootstrapContext; this.bootstrapContext = bootstrapContext;
this.deferredLogFactory = logFactory; this.deferredLogFactory = logFactory;
this.addListener(this.bootstrapContext);
}
protected void onBootstrapContextClosed(ConfigurableBootstrapContext bootstrapContext, ConfigurableApplicationContext applicationContext) {
onBootstrapContextClosed(applicationContext);
}
protected void onBootstrapContextClosed(ConfigurableApplicationContext applicationContext) {
}
private void addListener(ConfigurableBootstrapContext bootstrapContext) {
BootstrapContextListenerComposite listener = BootstrapContextListenerComposite.getInstance();
listener.addListener(this);
bootstrapContext.addCloseListener(listener);
} }
} }
\ No newline at end of file
...@@ -5,10 +5,11 @@ import cn.hutool.core.util.ArrayUtil; ...@@ -5,10 +5,11 @@ import cn.hutool.core.util.ArrayUtil;
import com.schbrain.common.constants.DateTimeFormatters; import com.schbrain.common.constants.DateTimeFormatters;
import com.schbrain.common.util.EnvUtils; import com.schbrain.common.util.EnvUtils;
import com.schbrain.common.util.PortUtils; import com.schbrain.common.util.PortUtils;
import com.schbrain.framework.support.spring.EnvironmentPostProcessorAdapter; import com.schbrain.framework.support.spring.EnvironmentPostProcessorLoggerAwareAdapter;
import org.springframework.boot.*; import org.springframework.boot.*;
import org.springframework.boot.actuate.autoconfigure.health.HealthProperties.Show; import org.springframework.boot.actuate.autoconfigure.health.HealthProperties.Show;
import org.springframework.boot.actuate.info.InfoPropertiesInfoContributor.Mode; import org.springframework.boot.actuate.info.InfoPropertiesInfoContributor.Mode;
import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor;
import org.springframework.boot.logging.DeferredLogFactory; import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.boot.web.server.Shutdown; import org.springframework.boot.web.server.Shutdown;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
...@@ -22,7 +23,12 @@ import java.util.*; ...@@ -22,7 +23,12 @@ import java.util.*;
* @author liaozan * @author liaozan
* @since 2021/12/18 * @since 2021/12/18
*/ */
public class DefaultPropertiesEnvironmentPostProcessor extends EnvironmentPostProcessorAdapter implements Ordered { public class DefaultPropertiesEnvironmentPostProcessor extends EnvironmentPostProcessorLoggerAwareAdapter implements Ordered {
/**
* set default properties after configData loaded
*/
public static final Integer DEFAULT_ORDER = ConfigDataEnvironmentPostProcessor.ORDER + 1;
private static final String SPRING_PROFILE_ACTIVE = "spring.profiles.active"; private static final String SPRING_PROFILE_ACTIVE = "spring.profiles.active";
private static final String DUBBO_REGISTER_KEY = "dubbo.registry.register"; private static final String DUBBO_REGISTER_KEY = "dubbo.registry.register";
...@@ -67,7 +73,7 @@ public class DefaultPropertiesEnvironmentPostProcessor extends EnvironmentPostPr ...@@ -67,7 +73,7 @@ public class DefaultPropertiesEnvironmentPostProcessor extends EnvironmentPostPr
@Override @Override
public int getOrder() { public int getOrder() {
return Ordered.LOWEST_PRECEDENCE; return DEFAULT_ORDER;
} }
private void configureActiveProfileIfPresent(ConfigurableEnvironment environment, Map<String, Object> defaultProperties) { private void configureActiveProfileIfPresent(ConfigurableEnvironment environment, Map<String, Object> defaultProperties) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment