upd
This commit is contained in:
parent
3aae139b28
commit
9581a6d39c
|
@ -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;
|
package cn.odboy.infra.context;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package cn.odboy.config.context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @date: 2020/6/9 17:02
|
||||||
|
* @since: 1.0
|
||||||
|
* @see {@link SpringContextHolder}
|
||||||
|
* 针对某些初始化方法,在SpringContextHolder 初始化前时,<br>
|
||||||
|
* 可提交一个 提交回调任务。<br>
|
||||||
|
* 在SpringContextHolder 初始化后,进行回调使用
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface CallBack {
|
||||||
|
/**
|
||||||
|
* 回调执行方法
|
||||||
|
*/
|
||||||
|
void executor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本回调任务名称
|
||||||
|
*
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
default String getCallBackName() {
|
||||||
|
return Thread.currentThread().getId() + ":" + this.getClass().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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<CallBack> 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> T getBean(String name) {
|
||||||
|
assertContextInjected();
|
||||||
|
return (T) applicationContext.getBean(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||||
|
*/
|
||||||
|
public static <T> T getBean(Class<T> requiredType) {
|
||||||
|
assertContextInjected();
|
||||||
|
return applicationContext.getBean(requiredType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取SpringBoot 配置信息
|
||||||
|
*
|
||||||
|
* @param property 属性key
|
||||||
|
* @param defaultValue 默认值
|
||||||
|
* @param requiredType 返回类型
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static <T> T getProperties(String property, T defaultValue, Class<T> 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> T getProperties(String property, Class<T> 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<String> getAllServiceBeanName() {
|
||||||
|
return new ArrayList<>(Arrays.asList(applicationContext
|
||||||
|
.getBeanNamesForAnnotation(Service.class)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
/**
|
||||||
|
* 消息类型:<br/>
|
||||||
|
* register 注册<br/>
|
||||||
|
* pullConfig 拉取配置<br/>
|
||||||
|
* updateConfig 更新配置<br/>
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ import org.springframework.stereotype.Component;
|
||||||
@Setter
|
@Setter
|
||||||
@Component
|
@Component
|
||||||
@ConfigurationProperties(prefix = "kenaito.config-center")
|
@ConfigurationProperties(prefix = "kenaito.config-center")
|
||||||
public class ConfigCenterProperties {
|
public class ConfigClientProperties {
|
||||||
private String server;
|
private String server;
|
||||||
private Integer port;
|
private Integer port;
|
||||||
private String dataId;
|
private String dataId;
|
|
@ -1,11 +1,9 @@
|
||||||
package cn.odboy.config.context;
|
package cn.odboy.config.context;
|
||||||
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.odboy.config.ConfigCenterProperties;
|
import cn.odboy.config.netty.ConfigClient;
|
||||||
import cn.odboy.config.netty.ConfigCenterClient;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.BeansException;
|
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.BeanFactoryPostProcessor;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
@ -25,7 +23,7 @@ import java.nio.file.Paths;
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
public class ConfigCenterConfigLoader {
|
public class ClientConfigLoader {
|
||||||
private static final String OS_TYPE_WIN = "win";
|
private static final String OS_TYPE_WIN = "win";
|
||||||
private static final String OS_TYPE_MAC = "mac";
|
private static final String OS_TYPE_MAC = "mac";
|
||||||
private static final String DEFAULT_PATH_WIN = "c:\\data";
|
private static final String DEFAULT_PATH_WIN = "c:\\data";
|
||||||
|
@ -55,21 +53,22 @@ public class ConfigCenterConfigLoader {
|
||||||
@Override
|
@Override
|
||||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||||
String defaultCacheDir = getDefaultCacheDir();
|
String defaultCacheDir = getDefaultCacheDir();
|
||||||
String server = environment.getProperty(DEFAULT_CONFIG_NAME_SERVER, String.class, DEFAULT_CONFIG_SERVER);
|
ClientProp.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);
|
ClientProp.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);
|
ClientProp.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);
|
ClientProp.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);
|
ClientProp.cacheDir = environment.getProperty(DEFAULT_CONFIG_NAME_CACHE_DIR, String.class, defaultCacheDir);
|
||||||
validateCacheDirPath(defaultCacheDir, cacheDir);
|
log.info("客户端属性: {}", ClientProp.toPrint());
|
||||||
createCacheDir(cacheDir);
|
validateCacheDirPath(defaultCacheDir, ClientProp.cacheDir);
|
||||||
ConfigCenterClient client = new ConfigCenterClient();
|
createCacheDir(ClientProp.cacheDir);
|
||||||
try {
|
try {
|
||||||
client.start(server, port);
|
ConfigClient client = new ConfigClient();
|
||||||
|
client.start(ClientProp.server, ClientProp.port);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
log.error("Netty Client Start Error", e);
|
log.error("Netty Client Start Error", e);
|
||||||
throw new RuntimeException(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<String, Object> configKv = client.fetchConfig();
|
// Map<String, Object> configKv = client.fetchConfig();
|
||||||
// MapPropertySource propertySource = new MapPropertySource("configCenter", configKv);
|
// MapPropertySource propertySource = new MapPropertySource("configCenter", configKv);
|
||||||
// environment.getPropertySources().addFirst(propertySource);
|
// environment.getPropertySources().addFirst(propertySource);
|
|
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
package cn.odboy.config.netty;
|
package cn.odboy.config.netty;
|
||||||
import cn.odboy.config.ConfigCenterProperties;
|
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
@ -11,7 +10,7 @@ import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ConfigCenterClient {
|
public class ConfigClient {
|
||||||
public void start(String server, Integer port) throws InterruptedException {
|
public void start(String server, Integer port) throws InterruptedException {
|
||||||
EventLoopGroup group = new NioEventLoopGroup();
|
EventLoopGroup group = new NioEventLoopGroup();
|
||||||
try {
|
try {
|
||||||
|
@ -21,7 +20,7 @@ public class ConfigCenterClient {
|
||||||
@Override
|
@Override
|
||||||
protected void initChannel(SocketChannel ch) throws Exception {
|
protected void initChannel(SocketChannel ch) throws Exception {
|
||||||
ChannelPipeline pipeline = ch.pipeline();
|
ChannelPipeline pipeline = ch.pipeline();
|
||||||
pipeline.addLast(new ConfigCenterClientHandler());
|
pipeline.addLast(new ConfigClientHandler());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
log.info("Netty Client Start...");
|
log.info("Netty Client Start...");
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,6 @@ kenaito:
|
||||||
config-center:
|
config-center:
|
||||||
server: 127.0.0.1
|
server: 127.0.0.1
|
||||||
port: 28002
|
port: 28002
|
||||||
data-id: kenaito-config-service
|
data-id: kenaito-config-demo
|
||||||
cache-dir: c:\\data
|
cache-dir: c:\\data
|
||||||
env: daily
|
env: daily
|
|
@ -2,6 +2,6 @@ kenaito:
|
||||||
config-center:
|
config-center:
|
||||||
server: 127.0.0.1
|
server: 127.0.0.1
|
||||||
port: 28002
|
port: 28002
|
||||||
data-id: kenaito-config-service
|
data-id: kenaito-config-demo
|
||||||
cache-dir: /home/admin/data
|
cache-dir: /home/admin/data
|
||||||
env: production
|
env: production
|
|
@ -2,6 +2,6 @@ kenaito:
|
||||||
config-center:
|
config-center:
|
||||||
server: 127.0.0.1
|
server: 127.0.0.1
|
||||||
port: 28002
|
port: 28002
|
||||||
data-id: kenaito-config-service
|
data-id: kenaito-config-demo
|
||||||
cache-dir: /home/admin/data
|
cache-dir: /home/admin/data
|
||||||
env: stage
|
env: stage
|
|
@ -7,15 +7,17 @@ import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
|
||||||
public class ConfigServerHandler extends ChannelInboundHandlerAdapter {
|
public class ConfigServerHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||||
|
System.err.println("当从Channel读取数据时被调用");
|
||||||
//System.out.println("从客户端读取到String:" + msg.toString());
|
//System.out.println("从客户端读取到String:" + msg.toString());
|
||||||
//System.out.println("从客户端读取到Object:" + ((User)msg).toString());
|
//System.out.println("从客户端读取到Object:" + ((User)msg).toString());
|
||||||
//测试用protostuff对对象编解码
|
//测试用protostuff对对象编解码
|
||||||
ByteBuf buf = (ByteBuf) msg;
|
ByteBuf buf = (ByteBuf) msg;
|
||||||
byte[] bytes = new byte[buf.readableBytes()];
|
byte[] bytes = new byte[buf.readableBytes()];
|
||||||
buf.readBytes(bytes);
|
buf.readBytes(bytes);
|
||||||
System.out.println("从客户端读取到Object:" + ProtostuffUtil.deserializer(bytes, ConfigKv.class));
|
System.err.println("从客户端读取到Object:" + ProtostuffUtil.deserializer(bytes, ConfigKv.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue