mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-08-05 08:23:54 +00:00
perf[protocol]:update config
This commit is contained in:
@@ -36,7 +36,6 @@
|
||||
<netty.version>4.1.84.Final</netty.version>
|
||||
<jprotobuf.version>2.4.17</jprotobuf.version>
|
||||
<kryo.version>5.3.0</kryo.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
|
||||
<!-- zookeeper -->
|
||||
<curator.version>5.3.0</curator.version>
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<netty.version>4.1.84.Final</netty.version>
|
||||
<jprotobuf.version>2.4.17</jprotobuf.version>
|
||||
<kryo.version>5.3.0</kryo.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
|
||||
<!-- zookeeper -->
|
||||
<curator.version>5.3.0</curator.version>
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<netty.version>4.1.84.Final</netty.version>
|
||||
<jprotobuf.version>2.4.17</jprotobuf.version>
|
||||
<kryo.version>5.3.0</kryo.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
|
||||
<!-- zookeeper -->
|
||||
<curator.version>5.3.0</curator.version>
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<netty.version>4.1.84.Final</netty.version>
|
||||
<jprotobuf.version>2.4.17</jprotobuf.version>
|
||||
<kryo.version>5.3.0</kryo.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
|
||||
<!-- zookeeper -->
|
||||
<curator.version>5.3.0</curator.version>
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<netty.version>4.1.84.Final</netty.version>
|
||||
<jprotobuf.version>2.4.17</jprotobuf.version>
|
||||
<kryo.version>5.3.0</kryo.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
|
||||
<!-- zookeeper -->
|
||||
<curator.version>5.3.0</curator.version>
|
||||
|
||||
@@ -36,7 +36,7 @@ public class NetConfig {
|
||||
/**
|
||||
* 生成协议列表
|
||||
*/
|
||||
private String protocolList;
|
||||
private String codeLanguages;
|
||||
|
||||
/**
|
||||
* 注册中心
|
||||
@@ -135,12 +135,12 @@ public class NetConfig {
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
public String getProtocolList() {
|
||||
return protocolList;
|
||||
public String getCodeLanguages() {
|
||||
return codeLanguages;
|
||||
}
|
||||
|
||||
public void setProtocolList(String protocolList) {
|
||||
this.protocolList = protocolList;
|
||||
public void setCodeLanguages(String codeLanguages) {
|
||||
this.codeLanguages = codeLanguages;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -31,6 +31,7 @@ import io.netty.buffer.ByteBuf;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
@@ -95,15 +96,14 @@ public class PacketService implements IPacketService {
|
||||
generateOperation.setFoldProtocol(netConfig.isFoldProtocol());
|
||||
generateOperation.setProtocolPath(netConfig.getProtocolPath());
|
||||
generateOperation.setProtocolParam(netConfig.getProtocolParam());
|
||||
var protocolArr = StringUtils.tokenize(netConfig.getProtocolList(), StringUtils.SEMICOLON_COMMA);
|
||||
var codeLanguageArr = StringUtils.tokenize(netConfig.getCodeLanguages(), ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
|
||||
|
||||
for (var protocolCode : protocolArr) {
|
||||
protocolCode = protocolCode.replaceAll(StringUtils.SPACE_REGEX, "");
|
||||
var codeLanguage = getProtocolList(protocolCode);
|
||||
if (CollectionUtils.isEmpty(codeLanguage)) {
|
||||
for (var codeLanguage : codeLanguageArr) {
|
||||
var codeLanguageSet = getProtocolList(codeLanguage);
|
||||
if (CollectionUtils.isEmpty(codeLanguageSet)) {
|
||||
continue;
|
||||
}
|
||||
generateOperation.getGenerateLanguages().addAll(codeLanguage);
|
||||
generateOperation.getGenerateLanguages().addAll(codeLanguageSet);
|
||||
}
|
||||
// 设置生成协议的过滤器
|
||||
GenerateProtocolFile.generateProtocolFilter = netGenerateProtocolFilter;
|
||||
@@ -127,20 +127,20 @@ public class PacketService implements IPacketService {
|
||||
|
||||
/**
|
||||
* 获取要生成协议列表
|
||||
* @param protocolCode
|
||||
* @param codeLanguage
|
||||
* @return
|
||||
*/
|
||||
private Set<CodeLanguage> getProtocolList(String protocolCode) {
|
||||
private Set<CodeLanguage> getProtocolList(String codeLanguage) {
|
||||
var languageSet = new HashSet<CodeLanguage>();
|
||||
boolean isNumeric = StringUtils.isNumeric(protocolCode);
|
||||
for (var codeLanguage : CodeLanguage.values()) {
|
||||
boolean isNumeric = StringUtils.isNumeric(codeLanguage);
|
||||
for (var language : CodeLanguage.values()) {
|
||||
if (isNumeric) {
|
||||
var protocolBit = Integer.valueOf(protocolCode);
|
||||
if ((protocolBit & codeLanguage.id) != 0) {
|
||||
languageSet.add(codeLanguage);
|
||||
var code = Integer.valueOf(codeLanguage);
|
||||
if ((code & language.id) != 0) {
|
||||
languageSet.add(language);
|
||||
}
|
||||
} else if (codeLanguage.name().equalsIgnoreCase(protocolCode)) {
|
||||
languageSet.add(codeLanguage);
|
||||
} else if (language.name().equalsIgnoreCase(codeLanguage)) {
|
||||
languageSet.add(language);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public class NetDefinitionParser implements BeanDefinitionParser {
|
||||
// 文件是否折叠
|
||||
resolvePlaceholder("fold-protocol", "foldProtocol", builder, element, parserContext);
|
||||
// 生成各种语言的协议列表
|
||||
resolvePlaceholder("protocol-list", "protocolList", builder, element, parserContext);
|
||||
resolvePlaceholder("code-languages", "codeLanguages", builder, element, parserContext);
|
||||
|
||||
resolvePlaceholder("protocol-path", "protocolPath", builder, element, parserContext);
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<xsd:attribute name="id" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="protocol-location" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="fold-protocol" type="xsd:string" default="false"/>
|
||||
<xsd:attribute name="protocol-list" type="xsd:string" default="0"/>
|
||||
<xsd:attribute name="code-languages" type="xsd:string"/>
|
||||
<xsd:attribute name="protocol-path" type="xsd:string"/>
|
||||
<xsd:attribute name="protocol-param" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<netty.version>4.1.84.Final</netty.version>
|
||||
<jprotobuf.version>2.4.17</jprotobuf.version>
|
||||
<kryo.version>5.3.0</kryo.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
|
||||
<!-- zookeeper -->
|
||||
<curator.version>5.3.0</curator.version>
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<netty.version>4.1.84.Final</netty.version>
|
||||
<jprotobuf.version>2.4.17</jprotobuf.version>
|
||||
<kryo.version>5.3.0</kryo.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
|
||||
<!-- zookeeper -->
|
||||
<curator.version>5.3.0</curator.version>
|
||||
@@ -157,12 +156,6 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.reflections</groupId>
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>${reflections.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
||||
@@ -42,7 +42,6 @@ import com.zfoo.protocol.util.StringUtils;
|
||||
import com.zfoo.protocol.xml.XmlProtocols;
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.NotFoundException;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.*;
|
||||
@@ -73,6 +72,9 @@ public class ProtocolAnalysis {
|
||||
// 临时变量,启动完成就会销毁,是一个基本类型序列化器
|
||||
private static Map<Class<?>, ISerializer> baseSerializerMap = new HashMap<>(128);
|
||||
|
||||
//临时变量,存储xml配置协议id,启动完成销毁
|
||||
private static Map<String, Short> protocolNameMap = new HashMap<>(MAX_PROTOCOL_NUM);
|
||||
|
||||
static {
|
||||
// 初始化基础类型序列化器
|
||||
baseSerializerMap.put(boolean.class, BooleanSerializer.INSTANCE);
|
||||
@@ -99,193 +101,201 @@ public class ProtocolAnalysis {
|
||||
*/
|
||||
public static synchronized void analyze(Set<Class<?>> protocolClassSet, GenerateOperation generateOperation) {
|
||||
AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName());
|
||||
try {
|
||||
// 检查协议类是否合法
|
||||
for (var protocolClass : protocolClassSet) {
|
||||
var protocolId = getProtocolIdAndCheckClass(protocolClass);
|
||||
AssertionUtils.isTrue(protocolId >= 0, "[class:{}]必须使用注解@Protocol注解标注或者使用[{}]字段", protocolClass.getCanonicalName(), PROTOCOL_ID);
|
||||
initProtocolClass(protocolId, protocolClass);
|
||||
}
|
||||
|
||||
// 协议id和协议信息对应起来
|
||||
for (var protocolClass : protocolClassSet) {
|
||||
var registration = parseProtocolRegistration(protocolClass, ProtocolModule.DEFAULT_PROTOCOL_MODULE);
|
||||
protocols[registration.protocolId()] = registration;
|
||||
}
|
||||
|
||||
// 通过指定类注册的协议,全部使用字节码增强
|
||||
var enhanceList = Arrays.stream(protocols).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
enhance(generateOperation, enhanceList);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
// 检查协议类是否合法
|
||||
for (var protocolClass : protocolClassSet) {
|
||||
var protocolId = getProtocolIdAndCheckClass(protocolClass);
|
||||
AssertionUtils.isTrue(protocolId >= 0, "[class:{}]必须使用注解@Protocol注解标注或者使用[{}]字段", protocolClass.getCanonicalName(), PROTOCOL_ID);
|
||||
initProtocolClass(protocolId, protocolClass);
|
||||
}
|
||||
|
||||
// 协议id和协议信息对应起来
|
||||
for (var protocolClass : protocolClassSet) {
|
||||
var registration = parseProtocolRegistration(protocolClass, ProtocolModule.DEFAULT_PROTOCOL_MODULE);
|
||||
protocols[registration.protocolId()] = registration;
|
||||
}
|
||||
|
||||
// 通过指定类注册的协议,全部使用字节码增强
|
||||
var enhanceList = Arrays.stream(protocols).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
enhance(generateOperation, enhanceList);
|
||||
}
|
||||
|
||||
public static synchronized void analyzeAuto(Set<Class<?>> protocolClassSet, GenerateOperation generateOperation) {
|
||||
AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName());
|
||||
try {
|
||||
// 获取所有协议类
|
||||
var relevantClassSet = new HashSet<>(protocolClassSet);
|
||||
for (var clazz : protocolClassSet) {
|
||||
relevantClassSet.addAll(ClassUtils.relevantClass(clazz));
|
||||
}
|
||||
|
||||
var relevantClassList = relevantClassSet.stream()
|
||||
.sorted((a, b) -> a.getCanonicalName().compareTo(b.getCanonicalName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 检查协议类是否合法
|
||||
var noProtocolIds = new ArrayList<Class<?>>();
|
||||
for (var protocolClass : relevantClassList) {
|
||||
var protocolId = getProtocolIdAndCheckClass(protocolClass);
|
||||
if (protocolId >= 0) {
|
||||
initProtocolClass(protocolId, protocolClass);
|
||||
} else {
|
||||
noProtocolIds.add(protocolClass);
|
||||
}
|
||||
}
|
||||
var countProtocolId = (short) 0;
|
||||
for (var protocolClass : noProtocolIds) {
|
||||
while (protocolClassMap.containsKey(countProtocolId)) {
|
||||
countProtocolId++;
|
||||
}
|
||||
initProtocolClass(countProtocolId, protocolClass);
|
||||
}
|
||||
|
||||
// 协议id和协议信息对应起来
|
||||
for (var protocolClass : relevantClassSet) {
|
||||
var registration = parseProtocolRegistration(protocolClass, ProtocolModule.DEFAULT_PROTOCOL_MODULE);
|
||||
protocols[registration.protocolId()] = registration;
|
||||
}
|
||||
|
||||
// 通过指定类注册的协议,全部使用字节码增强
|
||||
var enhanceList = Arrays.stream(protocols).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
enhance(generateOperation, enhanceList);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
// 获取所有协议类
|
||||
var relevantClassSet = new HashSet<>(protocolClassSet);
|
||||
for (var clazz : protocolClassSet) {
|
||||
relevantClassSet.addAll(ClassUtils.relevantClass(clazz));
|
||||
}
|
||||
|
||||
var relevantClassList = relevantClassSet.stream()
|
||||
.sorted((a, b) -> a.getCanonicalName().compareTo(b.getCanonicalName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 检查协议类是否合法
|
||||
var noProtocolIds = new ArrayList<Class<?>>();
|
||||
for (var protocolClass : relevantClassList) {
|
||||
var protocolId = getProtocolIdAndCheckClass(protocolClass);
|
||||
if (protocolId >= 0) {
|
||||
initProtocolClass(protocolId, protocolClass);
|
||||
} else {
|
||||
noProtocolIds.add(protocolClass);
|
||||
}
|
||||
}
|
||||
var countProtocolId = (short) 0;
|
||||
for (var protocolClass : noProtocolIds) {
|
||||
while (protocolClassMap.containsKey(countProtocolId)) {
|
||||
countProtocolId++;
|
||||
}
|
||||
initProtocolClass(countProtocolId, protocolClass);
|
||||
}
|
||||
|
||||
// 协议id和协议信息对应起来
|
||||
for (var protocolClass : relevantClassSet) {
|
||||
var registration = parseProtocolRegistration(protocolClass, ProtocolModule.DEFAULT_PROTOCOL_MODULE);
|
||||
protocols[registration.protocolId()] = registration;
|
||||
}
|
||||
|
||||
// 通过指定类注册的协议,全部使用字节码增强
|
||||
var enhanceList = Arrays.stream(protocols).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
enhance(generateOperation, enhanceList);
|
||||
}
|
||||
|
||||
public static synchronized void analyze(XmlProtocols xmlProtocols, GenerateOperation generateOperation) {
|
||||
if (xmlProtocols.isPackages()) {
|
||||
analyzePackage(xmlProtocols, generateOperation);
|
||||
return;
|
||||
}
|
||||
AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName());
|
||||
try {
|
||||
var enhanceList = new ArrayList<IProtocolRegistration>();
|
||||
|
||||
for (var moduleDefinition : xmlProtocols.getModules()) {
|
||||
var module = new ProtocolModule(moduleDefinition.getId(), moduleDefinition.getName());
|
||||
var protocolDefinitionMap = new HashMap<String, Boolean>();
|
||||
for (var moduleDefinition : xmlProtocols.getModules()) {
|
||||
var module = new ProtocolModule(moduleDefinition.getId(), moduleDefinition.getName());
|
||||
AssertionUtils.isTrue(module.getId() > 0, "[module:{}] [id:{}] 模块必须大于等于1", module.getName(), module.getId());
|
||||
AssertionUtils.isNull(modules[module.getId()], "duplicate [module:{}] [id:{}] Exception!", module.getName(), module.getId());
|
||||
|
||||
AssertionUtils.isTrue(module.getId() > 0, "[module:{}] [id:{}] 模块必须大于等于1", module.getName(), module.getId());
|
||||
AssertionUtils.isNull(modules[module.getId()], "duplicate [module:{}] [id:{}] Exception!", module.getName(), module.getId());
|
||||
AssertionUtils.notNull(moduleDefinition.getProtocols(), "[module:{}] does not have any protocols", module.getName());
|
||||
|
||||
modules[module.getId()] = module;
|
||||
|
||||
for (var protocolDefinition : moduleDefinition.getProtocols()) {
|
||||
var location = protocolDefinition.getLocation();
|
||||
var clazz = Class.forName(location);
|
||||
var protocolId = protocolDefinition.getId();
|
||||
|
||||
// 如果xml文件中没有填protocolId则只需要获取到protocolId即可
|
||||
if (protocolId < 0) {
|
||||
protocolId = getProtocolIdAndCheckClass(clazz);
|
||||
AssertionUtils.isTrue(protocolId >= 0, "[class:{}]在使用xml方式注册协议,如果xml没有提供协议号,则需要使用注解或者协议字段标注协议号", clazz.getCanonicalName());
|
||||
} else {
|
||||
var id = getProtocolIdAndCheckClass(clazz);
|
||||
// 使用xml方式注册协议可以,协议class不需要使用注解或者字段标注协议号
|
||||
if (id >= 0) {
|
||||
AssertionUtils.isTrue(protocolId == id, "[class:{}]协议序列号[{}]和协议文件里的协议序列号不相等", clazz.getCanonicalName(), PROTOCOL_ID);
|
||||
}
|
||||
}
|
||||
AssertionUtils.isTrue(protocolId >= moduleDefinition.getMinId(), "模块[{}]中的协议[{}]的协议号必须大于或者等于[{}]", moduleDefinition.getName(), clazz.getSimpleName(), moduleDefinition.getMinId());
|
||||
AssertionUtils.isTrue(protocolId < moduleDefinition.getMaxId(), "模块[{}]中的协议[{}]的协议号必须小于[{}]", moduleDefinition.getName(), clazz.getSimpleName(), moduleDefinition.getMaxId());
|
||||
initProtocolClass(protocolId, clazz);
|
||||
}
|
||||
modules[module.getId()] = module;
|
||||
if (CollectionUtils.isEmpty(moduleDefinition.getProtocols())) {
|
||||
continue;
|
||||
}
|
||||
for (var protocolDefinition : moduleDefinition.getProtocols()) {
|
||||
protocolDefinitionMap.put(protocolDefinition.getLocation(), protocolDefinition.isEnhance());
|
||||
protocolNameMap.put(protocolDefinition.getLocation(), protocolDefinition.getId());
|
||||
}
|
||||
|
||||
for (var moduleDefinition : xmlProtocols.getModules()) {
|
||||
var module = modules[moduleDefinition.getId()];
|
||||
for (var protocolDefinition : moduleDefinition.getProtocols()) {
|
||||
var location = protocolDefinition.getLocation();
|
||||
var clazz = Class.forName(location);
|
||||
var protocolId = ProtocolManager.protocolId(clazz);
|
||||
var registration = parseProtocolRegistration(clazz, module);
|
||||
if (protocolDefinition.isEnhance()) {
|
||||
enhanceList.add(registration);
|
||||
}
|
||||
// 注册协议
|
||||
protocols[protocolId] = registration;
|
||||
}
|
||||
}
|
||||
enhance(generateOperation, enhanceList);
|
||||
} catch (Exception e) {
|
||||
throw new UnknownException(e);
|
||||
}
|
||||
|
||||
// 获取所有IPack子类
|
||||
var packetClazzList = new HashSet<Class<?>>();
|
||||
if (xmlProtocols.isPackages()) {
|
||||
packetClazzList.addAll(scanPackageList(protocolDefinitionMap.keySet()));
|
||||
} else {
|
||||
packetClazzList.addAll(scanClassList(protocolDefinitionMap.keySet()));
|
||||
}
|
||||
|
||||
for (Class<?> clazz : packetClazzList) {
|
||||
var protocolId = getProtocolIdAndCheckClass(clazz);
|
||||
initProtocolClass(protocolId, clazz);
|
||||
}
|
||||
|
||||
var enhanceList = new ArrayList<IProtocolRegistration>();
|
||||
for (var moduleDefinition : xmlProtocols.getModules()) {
|
||||
var module = modules[moduleDefinition.getId()];
|
||||
for (Class<?> clazz : packetClazzList) {
|
||||
var protocolId = ProtocolManager.protocolId(clazz);
|
||||
if (protocolId < moduleDefinition.getMinId() || protocolId >= moduleDefinition.getMaxId()) {
|
||||
continue;
|
||||
}
|
||||
var registration = parseProtocolRegistration(clazz, module);
|
||||
if (xmlProtocols.isPackages() && !clazz.isAnnotationPresent(NotEnhance.class)) {
|
||||
enhanceList.add(registration);
|
||||
} else if (!xmlProtocols.isPackages() && protocolDefinitionMap.getOrDefault(clazz.getName(), true)) {
|
||||
enhanceList.add(registration);
|
||||
}
|
||||
// 注册协议
|
||||
protocols[protocolId] = registration;
|
||||
}
|
||||
}
|
||||
enhance(generateOperation, enhanceList);
|
||||
}
|
||||
|
||||
public static void analyzePackage(XmlProtocols xmlProtocols, GenerateOperation generateOperation) {
|
||||
AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName());
|
||||
try {
|
||||
var packageList = new HashSet<String>();
|
||||
for (var moduleDefinition : xmlProtocols.getModules()) {
|
||||
var module = new ProtocolModule(moduleDefinition.getId(), moduleDefinition.getName());
|
||||
var packageList = new HashSet<String>();
|
||||
for (var moduleDefinition : xmlProtocols.getModules()) {
|
||||
var module = new ProtocolModule(moduleDefinition.getId(), moduleDefinition.getName());
|
||||
|
||||
AssertionUtils.isTrue(module.getId() > 0, "[module:{}] [id:{}] 模块必须大于等于1", module.getName(), module.getId());
|
||||
AssertionUtils.isNull(modules[module.getId()], "duplicate [module:{}] [id:{}] Exception!", module.getName(), module.getId());
|
||||
AssertionUtils.notNull(moduleDefinition.getProtocols(), "[module:{}] does not have any protocols", module.getName());
|
||||
modules[module.getId()] = module;
|
||||
AssertionUtils.isTrue(module.getId() > 0, "[module:{}] [id:{}] 模块必须大于等于1", module.getName(), module.getId());
|
||||
AssertionUtils.isNull(modules[module.getId()], "duplicate [module:{}] [id:{}] Exception!", module.getName(), module.getId());
|
||||
AssertionUtils.notNull(moduleDefinition.getProtocols(), "[module:{}] does not have any protocols", module.getName());
|
||||
modules[module.getId()] = module;
|
||||
|
||||
for (var protocolDefinition : moduleDefinition.getProtocols()) {
|
||||
packageList.add(protocolDefinition.getLocation());
|
||||
}
|
||||
for (var protocolDefinition : moduleDefinition.getProtocols()) {
|
||||
packageList.add(protocolDefinition.getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有IPack子类
|
||||
var packetClazzList = scanClassList(packageList);
|
||||
// 获取所有IPack子类
|
||||
var packetClazzList = scanClassList(packageList);
|
||||
for (Class<?> clazz : packetClazzList) {
|
||||
var protocolId = getProtocolIdAndCheckClass(clazz);
|
||||
initProtocolClass(protocolId, clazz);
|
||||
}
|
||||
|
||||
var enhanceList = new ArrayList<IProtocolRegistration>();
|
||||
for (var moduleDefinition : xmlProtocols.getModules()) {
|
||||
var module = modules[moduleDefinition.getId()];
|
||||
for (Class<?> clazz : packetClazzList) {
|
||||
var protocolId = getProtocolIdAndCheckClass(clazz);
|
||||
initProtocolClass(protocolId, clazz);
|
||||
}
|
||||
|
||||
var enhanceList = new ArrayList<IProtocolRegistration>();
|
||||
for (var moduleDefinition : xmlProtocols.getModules()) {
|
||||
var module = modules[moduleDefinition.getId()];
|
||||
for (Class<?> clazz : packetClazzList) {
|
||||
var protocolId = ProtocolManager.protocolId(clazz);
|
||||
if (protocolId < moduleDefinition.getMinId() || protocolId >= moduleDefinition.getMaxId()) {
|
||||
continue;
|
||||
}
|
||||
var registration = parseProtocolRegistration(clazz, module);
|
||||
if (!clazz.isAnnotationPresent(NotEnhance.class)) {
|
||||
enhanceList.add(registration);
|
||||
}
|
||||
// 注册协议
|
||||
protocols[protocolId] = registration;
|
||||
var protocolId = ProtocolManager.protocolId(clazz);
|
||||
if (protocolId < moduleDefinition.getMinId() || protocolId >= moduleDefinition.getMaxId()) {
|
||||
continue;
|
||||
}
|
||||
var registration = parseProtocolRegistration(clazz, module);
|
||||
if (!clazz.isAnnotationPresent(NotEnhance.class)) {
|
||||
enhanceList.add(registration);
|
||||
}
|
||||
// 注册协议
|
||||
protocols[protocolId] = registration;
|
||||
}
|
||||
enhance(generateOperation, enhanceList);
|
||||
}
|
||||
enhance(generateOperation, enhanceList);
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scanPackageList(Set<String> packageList) {
|
||||
//获取该路径下所有类
|
||||
var clazzSet = new HashSet<String>();
|
||||
for (var packageName : packageList) {
|
||||
try {
|
||||
var clazzList = ClassUtils.getAllClasses(packageName);
|
||||
clazzSet.addAll(clazzList);
|
||||
} catch (Exception e) {
|
||||
throw new RunException("[{}]包扫描类异常", packageName, e);
|
||||
}
|
||||
}
|
||||
return scanClassList(clazzSet);
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scanClassList(Set<String> classList) {
|
||||
var clazzSet = new HashSet<Class<?>>();
|
||||
for (var className : classList) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(className);
|
||||
if (!IPacket.class.isAssignableFrom(clazz) || clazz.isInterface()) {
|
||||
continue;
|
||||
}
|
||||
clazzSet.add(clazz);
|
||||
} catch (Exception e) {
|
||||
throw new RunException("[class:{}]类不存在", className);
|
||||
}
|
||||
}
|
||||
return clazzSet;
|
||||
}
|
||||
|
||||
private static void enhance(GenerateOperation generateOperation, List<IProtocolRegistration> enhanceList) {
|
||||
try {
|
||||
enhanceProtocolBefore(generateOperation);
|
||||
enhanceProtocolRegistration(enhanceList);
|
||||
enhanceProtocolAfter(generateOperation);
|
||||
} catch (Exception e) {
|
||||
throw new UnknownException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<Class<? extends IPacket>> scanClassList(Set<String> packageList) {
|
||||
//获取该路径下所有类
|
||||
Reflections reflections = new Reflections(packageList);
|
||||
//获取继承了IPacket的所有类
|
||||
Set<Class<? extends IPacket>> classSet = reflections.getSubTypesOf(IPacket.class);
|
||||
return classSet.stream().filter(k -> !k.isInterface()).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private static void enhance(GenerateOperation generateOperation, List<IProtocolRegistration> enhanceList) throws IOException, ClassNotFoundException, NotFoundException, CannotCompileException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException, IllegalAccessException, InstantiationException {
|
||||
enhanceProtocolBefore(generateOperation);
|
||||
enhanceProtocolRegistration(enhanceList);
|
||||
enhanceProtocolAfter(generateOperation);
|
||||
}
|
||||
|
||||
private static void enhanceProtocolBefore(GenerateOperation generateOperation) throws IOException, ClassNotFoundException {
|
||||
// 检查协议格式
|
||||
checkAllProtocolClass();
|
||||
@@ -324,6 +334,7 @@ public class ProtocolAnalysis {
|
||||
subProtocolIdMap = null;
|
||||
protocolReserved = null;
|
||||
baseSerializerMap = null;
|
||||
protocolNameMap = null;
|
||||
|
||||
EnhanceUtils.clear();
|
||||
|
||||
@@ -635,6 +646,10 @@ public class ProtocolAnalysis {
|
||||
}
|
||||
} else {
|
||||
// 可能通过xml的方式注册协议,xml注册协议不需要注解和PROTOCOL_ID协议字段号
|
||||
Short id = protocolNameMap.get(clazz.getName());
|
||||
if (id != null) {
|
||||
protocolId = id;
|
||||
}
|
||||
}
|
||||
|
||||
return protocolId;
|
||||
|
||||
@@ -20,10 +20,10 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
@@ -31,6 +31,274 @@ import java.util.Set;
|
||||
*/
|
||||
public abstract class ClassUtils {
|
||||
|
||||
public final static String CLASS_FILE_EXT = ".class";
|
||||
|
||||
public final static String FILE_PROTOCOL = "file";
|
||||
|
||||
public final static String FILE_URL_PREFIX = "file:";
|
||||
|
||||
public final static String JAR_PROTOCOL = "jar";
|
||||
|
||||
public final static String JAR_URL_SEPARATOR = "!/";
|
||||
|
||||
/**
|
||||
* 扫描指定包下的class文件
|
||||
*
|
||||
* @param packageName 包名称(xxx.xxx)
|
||||
* @return 返回指定包下的class全称集合
|
||||
* @throws IOException 假如扫描失败,则抛出该异常
|
||||
*/
|
||||
public static Set<String> getAllClasses(String packageName) throws IOException {
|
||||
Set<String> classSet = new HashSet<>();
|
||||
String packagePath = packageName.replaceAll(StringUtils.PERIOD_REGEX, StringUtils.SLASH);
|
||||
Enumeration<URL> resourceUrls = getDefaultClassLoader().getResources(packagePath);
|
||||
while (resourceUrls.hasMoreElements()) {
|
||||
URL packageUrl = resourceUrls.nextElement();
|
||||
// 如果是以文件的形式保存在服务器上
|
||||
if (isFileProtocol(packageUrl)) {
|
||||
// file类型的扫描
|
||||
File file = getFile(packageUrl);
|
||||
// 以文件的方式扫描整个包下的文件 并添加到集合中
|
||||
findClassesInPackageByFile(packageName, file, classSet);
|
||||
} else if (isJarProtocol(packageUrl)) {
|
||||
findClassesInJarFile(packageName, packageUrl, classSet);
|
||||
}
|
||||
}
|
||||
return classSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描jar文件中的class
|
||||
*
|
||||
* @param packageName
|
||||
* 包名称
|
||||
* @param packageUrl
|
||||
* jar的url
|
||||
* @param classSet
|
||||
* class全路径集合
|
||||
* @throws IOException 假如解析出现io异常时,则抛出该异常
|
||||
*/
|
||||
private static void findClassesInJarFile(String packageName, URL packageUrl,
|
||||
Set<String> classSet) throws IOException {
|
||||
URLConnection con = packageUrl.openConnection();
|
||||
JarFile jarFile = null;
|
||||
String jarFileUrl = "";
|
||||
boolean closeJarFile = true;
|
||||
|
||||
if (con instanceof JarURLConnection) {
|
||||
JarURLConnection jarCon = (JarURLConnection) con;
|
||||
useCachesIfNecessary(jarCon);
|
||||
jarFile = jarCon.getJarFile();
|
||||
jarFileUrl = jarCon.getJarFileURL().toExternalForm();
|
||||
closeJarFile = !jarCon.getUseCaches();
|
||||
} else {
|
||||
//不是JarURLConnection->需要依赖于URL文件解析。
|
||||
//我们假设URL的格式为“jar:path!/entry”,只要遵循条目格式,协议就是任意的。
|
||||
//我们还将处理带和不带前导“file:”前缀的路径。
|
||||
String urlFile = packageUrl.getFile();
|
||||
try {
|
||||
int separatorIndex = urlFile.indexOf(JAR_URL_SEPARATOR);
|
||||
if (separatorIndex != -1) {
|
||||
jarFileUrl = urlFile.substring(0, separatorIndex);
|
||||
jarFile = getJarFile(jarFileUrl);
|
||||
} else {
|
||||
jarFile = new JarFile(urlFile);
|
||||
jarFileUrl = urlFile;
|
||||
}
|
||||
closeJarFile = true;
|
||||
} catch (Exception ex) {
|
||||
throw new RunException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (jarFile == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
classSet.addAll(findByJarFile(packageName, jarFile));
|
||||
} finally {
|
||||
if (closeJarFile) {
|
||||
jarFile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定jar文件中所有class名称(包名+类名称)格式为xx.xx.yy
|
||||
*
|
||||
* @param jarFile jar文件
|
||||
* @return class名称集合, 假如参数为null,返回大小为0的集合
|
||||
*/
|
||||
public Set<String> findByJarFile(JarFile jarFile) {
|
||||
return findByJarFile(StringUtils.EMPTY, jarFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定jar文件中所有class名称(包名+类名称) xx.xx.yy
|
||||
*
|
||||
* @param packageName 包名前缀xx.xx
|
||||
* @param jarFile jar文件
|
||||
* @return class名称集合, 假如参数为null,返回大小为0的集合
|
||||
*/
|
||||
public static Set<String> findByJarFile(String packageName, JarFile jarFile) {
|
||||
Set<String> classSet = new HashSet<>();
|
||||
if (jarFile == null) {
|
||||
return classSet;
|
||||
}
|
||||
String packageBasePath = packageName.replaceAll(StringUtils.PERIOD_REGEX, StringUtils.SLASH);
|
||||
if (!"".equals(packageBasePath) && !packageBasePath.endsWith("/")) {
|
||||
// 根条目路径必须以斜杠结束,以允许正确的匹配。匹配sunjre在这里不返回斜杠,但是beajrockit返回。
|
||||
packageBasePath = packageBasePath + StringUtils.SLASH;
|
||||
}
|
||||
for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements();) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
String entryPath = entry.getName();
|
||||
if (entryPath.startsWith(packageBasePath)) {
|
||||
int index = entryPath.indexOf(CLASS_FILE_EXT);
|
||||
String relativePath = entryPath.substring(0, index);
|
||||
String className = relativePath.replaceAll(StringUtils.SLASH, StringUtils.PERIOD);
|
||||
classSet.add(className);
|
||||
}
|
||||
}
|
||||
return classSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将给定的jar文件URL解析为JarFile对象
|
||||
*
|
||||
* @param jarFileUrl
|
||||
*/
|
||||
private static JarFile getJarFile(String jarFileUrl) throws IOException {
|
||||
if (jarFileUrl.startsWith(FILE_URL_PREFIX)) {
|
||||
try {
|
||||
return new JarFile(toURI(jarFileUrl).getSchemeSpecificPart());
|
||||
} catch (Exception ex) {
|
||||
return new JarFile(jarFileUrl.substring(FILE_URL_PREFIX.length()));
|
||||
}
|
||||
} else {
|
||||
return new JarFile(jarFileUrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 以文件的方式扫描整个包下的文件 并添加到集合中
|
||||
*
|
||||
* @param packageName
|
||||
* 包名称
|
||||
* @param dirOrFile
|
||||
* 查找包对应的文件或文件夹
|
||||
* @param classSet
|
||||
* class全路径集合
|
||||
*/
|
||||
private static void findClassesInPackageByFile(String packageName, File dirOrFile,
|
||||
Set<String> classSet) {
|
||||
// 如果不存在或者 也不是目录就直接返回
|
||||
if (!dirOrFile.exists()) {
|
||||
return;
|
||||
}
|
||||
if (!dirOrFile.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
// 如果存在 就获取包下的所有文件 包括目录
|
||||
File[] dirFiles = dirOrFile.listFiles();
|
||||
if (dirFiles == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 循环所有文件
|
||||
for (File file : dirFiles) {
|
||||
String name = file.getName();
|
||||
// 如果是目录 则继续扫描
|
||||
if (file.isDirectory()) {
|
||||
findClassesInPackageByFile(packageName + "." + name, file, classSet);
|
||||
} else {
|
||||
String filename = file.getName();
|
||||
// 如果是java类文件 去掉后面的.class 只留下类名
|
||||
String className = filename.substring(0, filename.length() - CLASS_FILE_EXT.length());
|
||||
className = packageName + "." + className;
|
||||
//去掉前缀“.”
|
||||
if (className.startsWith(".")) {
|
||||
className = className.substring(1);
|
||||
}
|
||||
classSet.add(className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static File getFile(URL url) {
|
||||
if (!FILE_PROTOCOL.equals(url.getProtocol())) {
|
||||
throw new IllegalArgumentException("给定的URL无法解析为绝对文件路径: " + url);
|
||||
}
|
||||
try {
|
||||
return new File(toURI(url).getSchemeSpecificPart());
|
||||
} catch (Exception ex) {
|
||||
return new File(url.getFile());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用给定的URL创建URI
|
||||
* 用“%20”编码替换URI的空格。
|
||||
* @param url 要转换为URI实例的URL
|
||||
* @return URI对象
|
||||
* @see java.net.URL#toURI()
|
||||
*/
|
||||
public static URI toURI(URL url) {
|
||||
return toURI(url.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 用给定的字符串创建URI
|
||||
* 用“%20”编码替换URI的空格。
|
||||
* @param location 要转换为URI实例的字符串
|
||||
* @return URI对象
|
||||
*/
|
||||
public static URI toURI(String location) {
|
||||
try {
|
||||
return new URI(location.replace(" ", "%20"));
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RunException("uri配置错误");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断给定的URL是不是file协议
|
||||
*
|
||||
* @param url url
|
||||
* @return 假如是file协议,返回true,否则返回false
|
||||
*/
|
||||
public static boolean isFileProtocol(URL url){
|
||||
if (url == null) {
|
||||
return false;
|
||||
}
|
||||
return FILE_PROTOCOL.equals(url.getProtocol());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断给定的URL是不是Jar协议
|
||||
*
|
||||
* @param url url
|
||||
* @return 假如是Jar协议,返回true,否则返回false
|
||||
*/
|
||||
public static boolean isJarProtocol(URL url){
|
||||
if (url == null) {
|
||||
return false;
|
||||
}
|
||||
String protocol = url.getProtocol();
|
||||
return JAR_PROTOCOL.equals(protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在给定的连接上设置“useCaches”标志,对于基于JNLP的资源,设置false,其他资源该标志保留原样
|
||||
*
|
||||
* @param urlConnection urlConnection
|
||||
*/
|
||||
public static void useCachesIfNecessary(URLConnection urlConnection){
|
||||
if (urlConnection != null) {
|
||||
urlConnection.setUseCaches(urlConnection.getClass().getSimpleName().startsWith("JNLP"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从类路径中读取文件
|
||||
*
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.zfoo.protocol.collection.ArrayUtils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@@ -485,21 +486,14 @@ public abstract class StringUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是数字
|
||||
* 判断是否是正数
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isNumeric(String str) {
|
||||
if(str == null) {
|
||||
return false;
|
||||
}
|
||||
int sz = str.length();
|
||||
for(int i = 0; i < sz; i++) {
|
||||
if (!Character.isDigit(str.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
Pattern pattern = Pattern.compile("[0-9]*");
|
||||
Matcher isNum = pattern.matcher(str);
|
||||
return isNum.matches();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<netty.version>4.1.84.Final</netty.version>
|
||||
<jprotobuf.version>2.4.17</jprotobuf.version>
|
||||
<kryo.version>5.3.0</kryo.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
|
||||
<!-- zookeeper -->
|
||||
<curator.version>5.3.0</curator.version>
|
||||
|
||||
@@ -166,24 +166,18 @@ public abstract class SchedulerBus {
|
||||
/**
|
||||
* 不断执行的周期循环任务
|
||||
*/
|
||||
public static void scheduleAtFixedRate(Runnable runnable, long period, TimeUnit unit) {
|
||||
if (SchedulerContext.isStop()) {
|
||||
return;
|
||||
}
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long period, TimeUnit unit) {
|
||||
|
||||
executor.scheduleAtFixedRate(SafeRunnable.valueOf(runnable), 0, period, unit);
|
||||
return executor.scheduleAtFixedRate(SafeRunnable.valueOf(runnable), 0, period, unit);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 固定延迟执行的任务
|
||||
*/
|
||||
public static void schedule(Runnable runnable, long delay, TimeUnit unit) {
|
||||
if (SchedulerContext.isStop()) {
|
||||
return;
|
||||
}
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay, TimeUnit unit) {
|
||||
|
||||
executor.schedule(SafeRunnable.valueOf(runnable), delay, unit);
|
||||
return executor.schedule(SafeRunnable.valueOf(runnable), delay, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<netty.version>4.1.84.Final</netty.version>
|
||||
<jprotobuf.version>2.4.17</jprotobuf.version>
|
||||
<kryo.version>5.3.0</kryo.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
|
||||
<!-- zookeeper -->
|
||||
<curator.version>5.3.0</curator.version>
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<netty.version>4.1.84.Final</netty.version>
|
||||
<jprotobuf.version>2.4.17</jprotobuf.version>
|
||||
<kryo.version>5.3.0</kryo.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
|
||||
<!-- zookeeper -->
|
||||
<curator.version>5.3.0</curator.version>
|
||||
|
||||
Reference in New Issue
Block a user