diff --git a/kenaito-common/src/main/java/cn/odboy/infra/context/CallBack.java b/kenaito-common/src/main/java/cn/odboy/infra/context/CallBack.java
index 2a258bd..d062614 100644
--- a/kenaito-common/src/main/java/cn/odboy/infra/context/CallBack.java
+++ b/kenaito-common/src/main/java/cn/odboy/infra/context/CallBack.java
@@ -1,18 +1,4 @@
-/*
- * Copyright 2019-2020 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+
package cn.odboy.infra.context;
diff --git a/kenaito-config-common/src/main/java/cn/odboy/config/context/CallBack.java b/kenaito-config-common/src/main/java/cn/odboy/config/context/CallBack.java
new file mode 100644
index 0000000..b60ffda
--- /dev/null
+++ b/kenaito-config-common/src/main/java/cn/odboy/config/context/CallBack.java
@@ -0,0 +1,27 @@
+package cn.odboy.config.context;
+
+/**
+ * @date: 2020/6/9 17:02
+ * @since: 1.0
+ * @see {@link SpringContextHolder}
+ * 针对某些初始化方法,在SpringContextHolder 初始化前时,
+ * 可提交一个 提交回调任务。
+ * 在SpringContextHolder 初始化后,进行回调使用
+ */
+
+public interface CallBack {
+ /**
+ * 回调执行方法
+ */
+ void executor();
+
+ /**
+ * 本回调任务名称
+ *
+ * @return /
+ */
+ default String getCallBackName() {
+ return Thread.currentThread().getId() + ":" + this.getClass().getName();
+ }
+}
+
diff --git a/kenaito-config-common/src/main/java/cn/odboy/config/context/SpringContextHolder.java b/kenaito-config-common/src/main/java/cn/odboy/config/context/SpringContextHolder.java
new file mode 100644
index 0000000..1379562
--- /dev/null
+++ b/kenaito-config-common/src/main/java/cn/odboy/config/context/SpringContextHolder.java
@@ -0,0 +1,140 @@
+package cn.odboy.config.context;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@Slf4j
+public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
+
+ private static ApplicationContext applicationContext = null;
+ private static final List CALL_BACKS = new ArrayList<>();
+ private static boolean addCallback = true;
+
+ /**
+ * 针对 某些初始化方法,在SpringContextHolder 未初始化时 提交回调方法。
+ * 在SpringContextHolder 初始化后,进行回调使用
+ *
+ * @param callBack 回调函数
+ */
+ public synchronized static void addCallBacks(CallBack callBack) {
+ if (addCallback) {
+ SpringContextHolder.CALL_BACKS.add(callBack);
+ } else {
+ log.warn("CallBack:{} 已无法添加!立即执行", callBack.getCallBackName());
+ callBack.executor();
+ }
+ }
+
+ /**
+ * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
+ */
+ @SuppressWarnings("unchecked")
+ public static T getBean(String name) {
+ assertContextInjected();
+ return (T) applicationContext.getBean(name);
+ }
+
+ /**
+ * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
+ */
+ public static T getBean(Class requiredType) {
+ assertContextInjected();
+ return applicationContext.getBean(requiredType);
+ }
+
+ /**
+ * 获取SpringBoot 配置信息
+ *
+ * @param property 属性key
+ * @param defaultValue 默认值
+ * @param requiredType 返回类型
+ * @return /
+ */
+ public static T getProperties(String property, T defaultValue, Class requiredType) {
+ T result = defaultValue;
+ try {
+ result = getBean(Environment.class).getProperty(property, requiredType);
+ } catch (Exception ignored) {
+ }
+ return result;
+ }
+
+ /**
+ * 获取SpringBoot 配置信息
+ *
+ * @param property 属性key
+ * @return /
+ */
+ public static String getProperties(String property) {
+ return getProperties(property, null, String.class);
+ }
+
+ /**
+ * 获取SpringBoot 配置信息
+ *
+ * @param property 属性key
+ * @param requiredType 返回类型
+ * @return /
+ */
+ public static T getProperties(String property, Class requiredType) {
+ return getProperties(property, null, requiredType);
+ }
+
+ /**
+ * 检查ApplicationContext不为空.
+ */
+ private static void assertContextInjected() {
+ if (applicationContext == null) {
+ throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext" +
+ ".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder.");
+ }
+ }
+
+ /**
+ * 清除SpringContextHolder中的ApplicationContext为Null.
+ */
+ private static void clearHolder() {
+ log.debug("清除SpringContextHolder中的ApplicationContext:"
+ + applicationContext);
+ applicationContext = null;
+ }
+
+ @Override
+ public void destroy() {
+ SpringContextHolder.clearHolder();
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ if (SpringContextHolder.applicationContext != null) {
+ log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
+ }
+ SpringContextHolder.applicationContext = applicationContext;
+ if (addCallback) {
+ for (CallBack callBack : SpringContextHolder.CALL_BACKS) {
+ callBack.executor();
+ }
+ CALL_BACKS.clear();
+ }
+ SpringContextHolder.addCallback = false;
+ }
+
+ /**
+ * 获取 @Service 的所有 bean 名称
+ *
+ * @return /
+ */
+ public static List getAllServiceBeanName() {
+ return new ArrayList<>(Arrays.asList(applicationContext
+ .getBeanNamesForAnnotation(Service.class)));
+ }
+}
diff --git a/kenaito-config-common/src/main/java/cn/odboy/config/model/Message.java b/kenaito-config-common/src/main/java/cn/odboy/config/model/Message.java
new file mode 100644
index 0000000..7ca1983
--- /dev/null
+++ b/kenaito-config-common/src/main/java/cn/odboy/config/model/Message.java
@@ -0,0 +1,21 @@
+package cn.odboy.config.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class Message implements Serializable {
+ /**
+ * 消息类型:
+ * register 注册
+ * pullConfig 拉取配置
+ * updateConfig 更新配置
+ */
+ private String type;
+
+}
diff --git a/kenaito-config-core/src/main/java/cn/odboy/config/ConfigCenterProperties.java b/kenaito-config-core/src/main/java/cn/odboy/config/ConfigClientProperties.java
similarity index 91%
rename from kenaito-config-core/src/main/java/cn/odboy/config/ConfigCenterProperties.java
rename to kenaito-config-core/src/main/java/cn/odboy/config/ConfigClientProperties.java
index ea3547f..e05185e 100644
--- a/kenaito-config-core/src/main/java/cn/odboy/config/ConfigCenterProperties.java
+++ b/kenaito-config-core/src/main/java/cn/odboy/config/ConfigClientProperties.java
@@ -9,7 +9,7 @@ import org.springframework.stereotype.Component;
@Setter
@Component
@ConfigurationProperties(prefix = "kenaito.config-center")
-public class ConfigCenterProperties {
+public class ConfigClientProperties {
private String server;
private Integer port;
private String dataId;
diff --git a/kenaito-config-core/src/main/java/cn/odboy/config/context/ConfigCenterConfigLoader.java b/kenaito-config-core/src/main/java/cn/odboy/config/context/ClientConfigLoader.java
similarity index 78%
rename from kenaito-config-core/src/main/java/cn/odboy/config/context/ConfigCenterConfigLoader.java
rename to kenaito-config-core/src/main/java/cn/odboy/config/context/ClientConfigLoader.java
index f8edbab..f4f7b98 100644
--- a/kenaito-config-core/src/main/java/cn/odboy/config/context/ConfigCenterConfigLoader.java
+++ b/kenaito-config-core/src/main/java/cn/odboy/config/context/ClientConfigLoader.java
@@ -1,11 +1,9 @@
package cn.odboy.config.context;
import cn.hutool.core.io.FileUtil;
-import cn.odboy.config.ConfigCenterProperties;
-import cn.odboy.config.netty.ConfigCenterClient;
+import cn.odboy.config.netty.ConfigClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Bean;
@@ -25,7 +23,7 @@ import java.nio.file.Paths;
*/
@Slf4j
@Configuration
-public class ConfigCenterConfigLoader {
+public class ClientConfigLoader {
private static final String OS_TYPE_WIN = "win";
private static final String OS_TYPE_MAC = "mac";
private static final String DEFAULT_PATH_WIN = "c:\\data";
@@ -55,21 +53,22 @@ public class ConfigCenterConfigLoader {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String defaultCacheDir = getDefaultCacheDir();
- String server = environment.getProperty(DEFAULT_CONFIG_NAME_SERVER, String.class, DEFAULT_CONFIG_SERVER);
- Integer port = environment.getProperty(DEFAULT_CONFIG_NAME_PORT, Integer.class, DEFAULT_CONFIG_PORT);
- String env = environment.getProperty(DEFAULT_CONFIG_NAME_ENV, String.class, DEFAULT_CONFIG_ENV);
- String dataId = environment.getProperty(DEFAULT_CONFIG_NAME_DATA_ID, String.class, DEFAULT_CONFIG_DATA_ID);
- String cacheDir = environment.getProperty(DEFAULT_CONFIG_NAME_CACHE_DIR, String.class, defaultCacheDir);
- validateCacheDirPath(defaultCacheDir, cacheDir);
- createCacheDir(cacheDir);
- ConfigCenterClient client = new ConfigCenterClient();
+ ClientProp.server = environment.getProperty(DEFAULT_CONFIG_NAME_SERVER, String.class, DEFAULT_CONFIG_SERVER);
+ ClientProp.port = environment.getProperty(DEFAULT_CONFIG_NAME_PORT, Integer.class, DEFAULT_CONFIG_PORT);
+ ClientProp.env = environment.getProperty(DEFAULT_CONFIG_NAME_ENV, String.class, DEFAULT_CONFIG_ENV);
+ ClientProp.dataId = environment.getProperty(DEFAULT_CONFIG_NAME_DATA_ID, String.class, DEFAULT_CONFIG_DATA_ID);
+ ClientProp.cacheDir = environment.getProperty(DEFAULT_CONFIG_NAME_CACHE_DIR, String.class, defaultCacheDir);
+ log.info("客户端属性: {}", ClientProp.toPrint());
+ validateCacheDirPath(defaultCacheDir, ClientProp.cacheDir);
+ createCacheDir(ClientProp.cacheDir);
try {
- client.start(server, port);
+ ConfigClient client = new ConfigClient();
+ client.start(ClientProp.server, ClientProp.port);
} catch (InterruptedException e) {
log.error("Netty Client Start Error", e);
throw new RuntimeException(e);
}
-// ConfigCenterClient client = new ConfigCenterClient("http://your-config-center-url/config");
+// ConfigClient client = new ConfigClient("http://your-config-center-url/config");
// Map configKv = client.fetchConfig();
// MapPropertySource propertySource = new MapPropertySource("configCenter", configKv);
// environment.getPropertySources().addFirst(propertySource);
diff --git a/kenaito-config-core/src/main/java/cn/odboy/config/context/ClientProp.java b/kenaito-config-core/src/main/java/cn/odboy/config/context/ClientProp.java
new file mode 100644
index 0000000..780a440
--- /dev/null
+++ b/kenaito-config-core/src/main/java/cn/odboy/config/context/ClientProp.java
@@ -0,0 +1,25 @@
+package cn.odboy.config.context;
+
+/**
+ * 客户端属性
+ *
+ * @author odboy
+ * @date 2024-12-03
+ */
+public class ClientProp {
+ public static String server;
+ public static Integer port;
+ public static String env;
+ public static String dataId;
+ public static String cacheDir;
+
+ public static String toPrint() {
+ return String.format("server: %s, port: %s, env: %s, dataId: %s, cacheDir: %s",
+ server,
+ port,
+ env,
+ dataId,
+ cacheDir
+ );
+ }
+}
diff --git a/kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigCenterClientHandler.java b/kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigCenterClientHandler.java
deleted file mode 100644
index 121a05d..0000000
--- a/kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigCenterClientHandler.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package cn.odboy.config.netty;
-
-import cn.odboy.config.model.ConfigKv;
-import cn.odboy.config.util.ProtostuffUtil;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelHandlerContext;
-public class ConfigCenterClientHandler extends ChannelInboundHandlerAdapter {
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- System.out.println("收到服务器消息:" + msg);
- }
-
- @Override
- public void channelActive(ChannelHandlerContext ctx) throws Exception {
- System.out.println("MyClientHandler发送数据");
- //ctx.writeAndFlush("测试String编解码");
- //测试对象编解码
- //ctx.writeAndFlush(new User(1,"zhuge"));
- //测试用protostuff对对象编解码
- ByteBuf buf = Unpooled.copiedBuffer(ProtostuffUtil.serializer(new ConfigKv("app.config", "张三")));
- ctx.writeAndFlush(buf);
- }
-}
diff --git a/kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigCenterClient.java b/kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigClient.java
similarity index 88%
rename from kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigCenterClient.java
rename to kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigClient.java
index 8dac3a3..a66b8df 100644
--- a/kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigCenterClient.java
+++ b/kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigClient.java
@@ -1,5 +1,4 @@
package cn.odboy.config.netty;
-import cn.odboy.config.ConfigCenterProperties;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
@@ -11,7 +10,7 @@ import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public class ConfigCenterClient {
+public class ConfigClient {
public void start(String server, Integer port) throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup();
try {
@@ -21,7 +20,7 @@ public class ConfigCenterClient {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
- pipeline.addLast(new ConfigCenterClientHandler());
+ pipeline.addLast(new ConfigClientHandler());
}
});
log.info("Netty Client Start...");
diff --git a/kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigClientHandler.java b/kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigClientHandler.java
new file mode 100644
index 0000000..0e43130
--- /dev/null
+++ b/kenaito-config-core/src/main/java/cn/odboy/config/netty/ConfigClientHandler.java
@@ -0,0 +1,41 @@
+package cn.odboy.config.netty;
+
+import cn.odboy.config.model.ConfigKv;
+import cn.odboy.config.util.ProtostuffUtil;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+public class ConfigClientHandler extends ChannelInboundHandlerAdapter {
+ @Override
+ public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
+ System.err.println("当Channel已经注册到它的EventLoop并且能够处理I/O时被调用");
+ }
+
+ @Override
+ public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
+ System.err.println("当Channel从它的EventLoop注销并且无法处理任何I/O时被调用");
+ }
+
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
+ System.err.println("当Channel处于活动状态(已经连接到它的远程节点)时被调用");
+ System.err.println("MyClientHandler发送数据");
+ //ctx.writeAndFlush("测试String编解码");
+ // 测试对象编解码
+ //ctx.writeAndFlush(new ConfigKv("app.config", "张三"));
+ // 测试用protostuff对对象编解码
+ ByteBuf buf = Unpooled.copiedBuffer(ProtostuffUtil.serializer(new ConfigKv("app.config", "张三")));
+ ctx.writeAndFlush(buf);
+ }
+
+ @Override
+ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+ System.err.println("当Channel离开活动状态并且不再连接到它的远程节点时被调用");
+ }
+
+ @Override
+ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+ System.err.println("收到服务器消息:" + msg);
+ }
+}
diff --git a/kenaito-config-demo/src/main/resources/config/application-daily.yml b/kenaito-config-demo/src/main/resources/config/application-daily.yml
index 0116afc..e06a223 100644
--- a/kenaito-config-demo/src/main/resources/config/application-daily.yml
+++ b/kenaito-config-demo/src/main/resources/config/application-daily.yml
@@ -2,6 +2,6 @@ kenaito:
config-center:
server: 127.0.0.1
port: 28002
- data-id: kenaito-config-service
+ data-id: kenaito-config-demo
cache-dir: c:\\data
env: daily
\ No newline at end of file
diff --git a/kenaito-config-demo/src/main/resources/config/application-production.yml b/kenaito-config-demo/src/main/resources/config/application-production.yml
index f287a61..a76488e 100644
--- a/kenaito-config-demo/src/main/resources/config/application-production.yml
+++ b/kenaito-config-demo/src/main/resources/config/application-production.yml
@@ -2,6 +2,6 @@ kenaito:
config-center:
server: 127.0.0.1
port: 28002
- data-id: kenaito-config-service
+ data-id: kenaito-config-demo
cache-dir: /home/admin/data
env: production
\ No newline at end of file
diff --git a/kenaito-config-demo/src/main/resources/config/application-stage.yml b/kenaito-config-demo/src/main/resources/config/application-stage.yml
index 27d1273..f8954ea 100644
--- a/kenaito-config-demo/src/main/resources/config/application-stage.yml
+++ b/kenaito-config-demo/src/main/resources/config/application-stage.yml
@@ -2,6 +2,6 @@ kenaito:
config-center:
server: 127.0.0.1
port: 28002
- data-id: kenaito-config-service
+ data-id: kenaito-config-demo
cache-dir: /home/admin/data
env: stage
\ No newline at end of file
diff --git a/kenaito-config-service/src/main/java/cn/odboy/infra/netty/ConfigServerHandler.java b/kenaito-config-service/src/main/java/cn/odboy/infra/netty/ConfigServerHandler.java
index 8c5ec83..489809e 100644
--- a/kenaito-config-service/src/main/java/cn/odboy/infra/netty/ConfigServerHandler.java
+++ b/kenaito-config-service/src/main/java/cn/odboy/infra/netty/ConfigServerHandler.java
@@ -7,15 +7,17 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ConfigServerHandler extends ChannelInboundHandlerAdapter {
+
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+ System.err.println("当从Channel读取数据时被调用");
//System.out.println("从客户端读取到String:" + msg.toString());
//System.out.println("从客户端读取到Object:" + ((User)msg).toString());
//测试用protostuff对对象编解码
ByteBuf buf = (ByteBuf) msg;
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
- System.out.println("从客户端读取到Object:" + ProtostuffUtil.deserializer(bytes, ConfigKv.class));
+ System.err.println("从客户端读取到Object:" + ProtostuffUtil.deserializer(bytes, ConfigKv.class));
}
@Override