perf[protocol]:update config

This commit is contained in:
meiwei
2023-08-25 21:00:51 +08:00
parent cf1d38940a
commit f1ae593739
18 changed files with 475 additions and 220 deletions
-1
View File
@@ -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>
-1
View File
@@ -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>
-1
View File
@@ -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>
-1
View File
@@ -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>
-1
View File
@@ -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);
+1 -1
View File
@@ -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>
-1
View File
@@ -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>
-7
View File
@@ -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();
}
}
-1
View File
@@ -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);
}
/**
-1
View File
@@ -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>
-1
View File
@@ -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>