【7.1.6】【scanner】调整资源扫描过程

pull/25/MERGE
fengshuonan 2022-01-15 18:26:28 +08:00
parent b0a72d5ebf
commit efae7d179a
5 changed files with 166 additions and 29 deletions

View File

@ -0,0 +1,100 @@
package cn.stylefeng.roses.kernel.scanner.api.context;
import cn.stylefeng.roses.kernel.scanner.api.enums.FieldTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.util.ClassTypeUtil;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
*
* <p>
*
*
* @author fengshuonan
* @date 2022/1/15 10:36
*/
public class MetadataContext {
/**
* keyid
*/
public static ConcurrentHashMap<String, Set<String>> META_DATA_CLASS_COUNT_CONTEXT = new ConcurrentHashMap<>();
/**
*
*
* @author fengshuonan
* @date 2022/1/15 10:47
*/
public static void addClassRecord(String uuid, String classPathName) {
Set<String> classRecords = META_DATA_CLASS_COUNT_CONTEXT.get(uuid);
if (classRecords == null) {
classRecords = new HashSet<>();
}
classRecords.add(classPathName);
META_DATA_CLASS_COUNT_CONTEXT.put(uuid, classRecords);
}
/**
*
*
* @author fengshuonan
* @date 2022/1/15 10:50
*/
public static boolean ensureFieldClassHaveParse(String uuid, String classPathName) {
Set<String> classRecords = META_DATA_CLASS_COUNT_CONTEXT.get(uuid);
if (classRecords == null) {
return false;
}
return classRecords.contains(classPathName);
}
/**
*
*
* @author fengshuonan
* @date 2022/1/15 10:50
*/
public static boolean ensureFieldClassHaveParse(String uuid, Type genericType) {
Set<String> classRecords = META_DATA_CLASS_COUNT_CONTEXT.get(uuid);
if (classRecords != null) {
// 获取字段类型如果是数组collection带实体的需要获取真实的实体类型
FieldTypeEnum classFieldType = ClassTypeUtil.getClassFieldType(genericType);
// 如果是对象类型,直接判断
if (classFieldType.equals(FieldTypeEnum.OBJECT)) {
return classRecords.contains(((Class<?>) genericType).getName());
}
// 数组类型,则获取数组的实体
if (classFieldType.equals(FieldTypeEnum.ARRAY_WITH_OBJECT)) {
Class<?> originClass = (Class<?>) genericType;
return classRecords.contains(originClass.getComponentType().getName());
}
// 集合类型,获取集合的真实类型
if (classFieldType.equals(FieldTypeEnum.COLLECTION_WITH_OBJECT)) {
// 获取泛型
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0];
return ensureFieldClassHaveParse(uuid, actualTypeArgument);
}
}
return false;
}
/**
*
*
* @author fengshuonan
* @date 2022/1/15 10:49
*/
public static void cleanContext() {
META_DATA_CLASS_COUNT_CONTEXT.clear();
}
}

View File

@ -1,10 +1,12 @@
package cn.stylefeng.roses.kernel.scanner.api.factory;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.scanner.api.context.MetadataContext;
import cn.stylefeng.roses.kernel.scanner.api.enums.FieldTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.factory.description.ClassDescriptionUtil;
import cn.stylefeng.roses.kernel.scanner.api.factory.description.FieldDescriptionUtil;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.FieldMetadata;
import cn.stylefeng.roses.kernel.scanner.api.util.ClassDescriptionUtil;
import cn.stylefeng.roses.kernel.scanner.api.util.ClassTypeUtil;
import cn.stylefeng.roses.kernel.scanner.api.util.FieldDescriptionUtil;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
@ -25,10 +27,12 @@ public class ClassDetailMetadataFactory {
/**
*
*
* @param fieldType class
* @param uuid context
* @author fengshuonan
* @date 2022/1/14 14:31
*/
public static Set<FieldMetadata> createFieldDetailMetadataSet(Type fieldType) {
public static Set<FieldMetadata> createFieldDetailMetadataSet(Type fieldType, String uuid) {
// 获取参数的类型枚举
FieldTypeEnum classFieldType = ClassTypeUtil.getClassFieldType(fieldType);
@ -54,7 +58,7 @@ public class ClassDetailMetadataFactory {
// 如果是带实体的数组,则加上实体对应的字段信息
Class<?> objArrayClass = (Class<?>) fieldType;
Class<?> objArrayComponentType = objArrayClass.getComponentType();
fieldMetadata = ClassDetailMetadataFactory.createFieldDetailMetadataSet(objArrayComponentType);
fieldMetadata = ClassDetailMetadataFactory.createFieldDetailMetadataSet(objArrayComponentType, uuid);
break;
case BASE_COLLECTION:
// 如果是基础集合因为不确定集合的内容所以使用Object来描述一下集合的具体内容
@ -66,16 +70,24 @@ public class ClassDetailMetadataFactory {
// 如果是集合里带的具体实体对象,则描述一下具体实体的数据结构
ParameterizedType collectionParameterizedType = (ParameterizedType) fieldType;
Type[] actualTypeArguments = collectionParameterizedType.getActualTypeArguments();
fieldMetadata = ClassDetailMetadataFactory.createFieldDetailMetadataSet(actualTypeArguments[0]);
fieldMetadata = ClassDetailMetadataFactory.createFieldDetailMetadataSet(actualTypeArguments[0], uuid);
break;
case OBJECT:
// 如果是实体对象,则描述实体对象的所有字段信息
Class<?> objectClass = (Class<?>) fieldType;
Field[] fields = objectClass.getDeclaredFields();
fieldMetadata = new LinkedHashSet<>();
// 在处理Object中所有字段之前将当前父类放进context所有子字段不能含有父类的类型否则会递归
MetadataContext.addClassRecord(uuid, objectClass.getName());
for (Field field : fields) {
// 获取字段的具体属性
FieldMetadata fieldInfo = FieldDescriptionUtil.createFieldMetadata(field);
FieldMetadata fieldInfo;
if (MetadataContext.ensureFieldClassHaveParse(uuid, field.getGenericType())) {
fieldInfo = FieldDescriptionUtil.createBasicMetadata(field, uuid);
} else {
fieldInfo = FieldDescriptionUtil.createFieldMetadata(field, uuid);
}
fieldMetadata.add(fieldInfo);
}
break;
@ -86,8 +98,16 @@ public class ClassDetailMetadataFactory {
Type rawType = objWithGenericParameterizedType.getRawType();
// 获取具体泛型
Type genericType = objWithGenericParameterizedType.getActualTypeArguments()[0];
// 判断带泛型的实体,有没有进行做字段解析,如果解析过,则跳过
String totalName = fieldType.getTypeName() + genericType.getTypeName();
if (MetadataContext.ensureFieldClassHaveParse(uuid, totalName)) {
return null;
}
MetadataContext.addClassRecord(uuid, totalName);
// 获取主体的所有字段信息
fieldMetadata = getEntityWithGenericFieldMetadataList(rawType, genericType);
fieldMetadata = getEntityWithGenericFieldMetadataList(rawType, genericType, uuid);
default:
}
@ -95,22 +115,25 @@ public class ClassDetailMetadataFactory {
}
/**
*
* PageResult<SysUser>
*
* @author fengshuonan
* @date 2022/1/14 18:51
*/
public static Set<FieldMetadata> getEntityWithGenericFieldMetadataList(Type fieldType, Type genericType) {
public static Set<FieldMetadata> getEntityWithGenericFieldMetadataList(Type fieldType, Type genericType, String uuid) {
if (fieldType instanceof Class<?>) {
Class<?> clazz = (Class<?>) fieldType;
// 获取主类型的所有带泛型的属性
Set<FieldMetadata> fieldDetailMetadataSet = createFieldDetailMetadataSet(clazz);
// 获取主类型的所有属性
Set<FieldMetadata> fieldDetailMetadataSet = createFieldDetailMetadataSet(clazz, uuid);
if (ObjectUtil.isEmpty(fieldDetailMetadataSet)) {
return null;
}
for (FieldMetadata fieldMetadata : fieldDetailMetadataSet) {
// 如果是带泛型集合如下情况List<T>,又或是直接 T 这种形式
if (FieldTypeEnum.COLLECTION_WITH_OBJECT.getCode().equals(fieldMetadata.getFieldType())
|| FieldTypeEnum.WITH_UNKNOWN_GENERIC.getCode().equals(fieldMetadata.getFieldType())) {
// 设置这个字段的子字段描述
fieldMetadata.setGenericFieldMetadata(createFieldDetailMetadataSet(genericType));
fieldMetadata.setGenericFieldMetadata(createFieldDetailMetadataSet(genericType, uuid));
}
// 如果T在携带在一个实体类上例如ResponseData<T>这种形式
@ -118,7 +141,7 @@ public class ClassDetailMetadataFactory {
// 设置这个字段的子字段描述
Set<FieldMetadata> current = null;
try {
current = getEntityWithGenericFieldMetadataList(Class.forName(fieldMetadata.getFieldClassPath()), genericType);
current = getEntityWithGenericFieldMetadataList(Class.forName(fieldMetadata.getFieldClassPath()), genericType, uuid);
} catch (ClassNotFoundException e) {
log.error("类无法找到" + fieldMetadata.getFieldClassPath(), e);
continue;

View File

@ -1,8 +1,8 @@
package cn.stylefeng.roses.kernel.scanner.api.factory;
import cn.stylefeng.roses.kernel.scanner.api.enums.FieldTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.factory.description.ClassDescriptionUtil;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.FieldMetadata;
import cn.stylefeng.roses.kernel.scanner.api.util.ClassDescriptionUtil;
import cn.stylefeng.roses.kernel.scanner.api.util.ClassTypeUtil;
import lombok.extern.slf4j.Slf4j;
@ -11,7 +11,7 @@ import java.lang.reflect.Type;
import java.util.Set;
/**
*
*
*
* @author fengshuonan
* @date 2022/1/13 13:49
@ -22,12 +22,13 @@ public class ClassMetadataFactory {
/**
* ClassParameterizedType
*
* @param type
* @param type class
* @param uuid context
* @return
* @author fengshuonan
* @date 2022/1/13 13:51
*/
public static FieldMetadata beginCreateFieldMetadata(Type type) {
public static FieldMetadata beginCreateFieldMetadata(Type type, String uuid) {
// 获取类型的枚举
FieldTypeEnum classFieldType = ClassTypeUtil.getClassFieldType(type);
@ -43,7 +44,7 @@ public class ClassMetadataFactory {
fieldMetadata = ClassDescriptionUtil.createClassMetadata(clazz, classFieldType);
// 补充类型的子信息
Set<FieldMetadata> fieldDetailMetadataSet = ClassDetailMetadataFactory.createFieldDetailMetadataSet(clazz);
Set<FieldMetadata> fieldDetailMetadataSet = ClassDetailMetadataFactory.createFieldDetailMetadataSet(clazz, uuid);
fieldMetadata.setGenericFieldMetadata(fieldDetailMetadataSet);
}
@ -55,7 +56,7 @@ public class ClassMetadataFactory {
FieldMetadata baseMetadata = ClassDescriptionUtil.createParameterizedMetadata(parameterizedType, classFieldType);
// 补充类型的子信息
Set<FieldMetadata> fieldDetailMetadataSet = ClassDetailMetadataFactory.createFieldDetailMetadataSet(type);
Set<FieldMetadata> fieldDetailMetadataSet = ClassDetailMetadataFactory.createFieldDetailMetadataSet(type, uuid);
baseMetadata.setGenericFieldMetadata(fieldDetailMetadataSet);
}

View File

@ -1,4 +1,4 @@
package cn.stylefeng.roses.kernel.scanner.api.factory.description;
package cn.stylefeng.roses.kernel.scanner.api.util;
import cn.hutool.core.util.IdUtil;
import cn.stylefeng.roses.kernel.scanner.api.enums.FieldMetadataTypeEnum;

View File

@ -1,4 +1,4 @@
package cn.stylefeng.roses.kernel.scanner.api.factory.description;
package cn.stylefeng.roses.kernel.scanner.api.util;
import cn.hutool.core.util.IdUtil;
import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription;
@ -6,8 +6,6 @@ import cn.stylefeng.roses.kernel.scanner.api.enums.FieldMetadataTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.enums.FieldTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.factory.ClassDetailMetadataFactory;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.FieldMetadata;
import cn.stylefeng.roses.kernel.scanner.api.util.ClassReflectUtil;
import cn.stylefeng.roses.kernel.scanner.api.util.ClassTypeUtil;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
@ -26,12 +24,12 @@ import java.util.Set;
public class FieldDescriptionUtil {
/**
*
*
*
* @author fengshuonan
* @date 2022/1/13 18:06
*/
public static FieldMetadata createFieldMetadata(Field field) {
public static FieldMetadata createBasicMetadata(Field field, String uuid) {
FieldMetadata fieldMetadataItem = new FieldMetadata();
// 设置唯一id
fieldMetadataItem.setMetadataId(IdUtil.fastSimpleUUID());
@ -59,12 +57,27 @@ public class FieldDescriptionUtil {
// 设置字段类型基本、数组、还是object
FieldTypeEnum classFieldType = ClassTypeUtil.getClassFieldType(genericType);
fieldMetadataItem.setFieldType(classFieldType.getCode());
// 根据情况,获取字段的具体子数据描述
Set<FieldMetadata> fieldDetailMetadataSet = ClassDetailMetadataFactory.createFieldDetailMetadataSet(genericType);
fieldMetadataItem.setGenericFieldMetadata(fieldDetailMetadataSet);
return fieldMetadataItem;
}
/**
* +
* <p>
*
*
* @author fengshuonan
* @date 2022/1/13 18:06
*/
public static FieldMetadata createFieldMetadata(Field field, String uuid) {
// 先组装基础数据
FieldMetadata fieldMetadata = createBasicMetadata(field, uuid);
// 组装子类型数据
Type genericType = field.getGenericType();
Set<FieldMetadata> fieldDetailMetadataSet = ClassDetailMetadataFactory.createFieldDetailMetadataSet(genericType, uuid);
fieldMetadata.setGenericFieldMetadata(fieldDetailMetadataSet);
return fieldMetadata;
}
/**
*
*