Feat:动态代码编译引擎成熟!

This commit is contained in:
wangyu 2021-01-05 23:00:53 +08:00
parent 9bfa1bc3d4
commit 7ad289e0a5
4 changed files with 72 additions and 13 deletions

View File

@ -3,14 +3,14 @@ package com.flyfish.framework.beans.meta;
import com.flyfish.framework.bean.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* bean控制器可以通过类直接返回bean信息
@ -29,10 +29,11 @@ public class BeanController {
*/
@GetMapping("")
public Result<List<BeanProperty>> beanInfo(String className) {
if (StringUtils.isBlank(className)) {
return Result.ok(Collections.emptyList());
}
try {
return Result.ok(Arrays.stream(BeanUtils.getPropertyDescriptors(ClassUtils.getClass(className)))
.map(BeanProperty::form)
.collect(Collectors.toList()));
return Result.ok(BeanProperty.from(BeanUtils.getPropertyDescriptors(ClassUtils.getClass(className))));
} catch (ClassNotFoundException e) {
log.error(e.getMessage(), e);
return Result.error(e.getMessage());

View File

@ -1,11 +1,14 @@
package com.flyfish.framework.beans.meta;
import com.flyfish.framework.beans.annotations.RestBean;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import java.beans.PropertyDescriptor;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@ -23,9 +26,24 @@ public class BeanProperty {
// bean属性的类型js类型
private BeanPropertyType type;
// 属性
private Map<String, Object> props;
// 类型为object时拥有子表单
private List<BeanProperty> children;
/**
* 类加载并解析属性
*
* @return 结果
*/
public static List<BeanProperty> from(PropertyDescriptor[] descriptors) {
return Arrays.stream(descriptors)
.filter(descriptor -> !"class".equals(descriptor.getName()))
.map(BeanProperty::form)
.collect(Collectors.toList());
}
/**
* 来自属性解释器构造
* 支持对象嵌套
@ -34,14 +52,23 @@ public class BeanProperty {
* @return 结果
*/
public static BeanProperty form(PropertyDescriptor descriptor) {
Class<?> clazz = descriptor.getPropertyType();
BeanProperty property = new BeanProperty();
property.setName(descriptor.getName());
property.setType(BeanPropertyType.of(descriptor.getPropertyType()));
property.setType(BeanPropertyType.of(descriptor));
if (property.getType() == BeanPropertyType.OBJECT) {
List<BeanProperty> children = Arrays.stream(BeanUtils.getPropertyDescriptors(descriptor.getPropertyType()))
.map(BeanProperty::form)
.collect(Collectors.toList());
property.setChildren(children);
// 有子bean注解才处理
if (clazz.isAnnotationPresent(SubBean.class)) {
List<BeanProperty> children = from(BeanUtils.getPropertyDescriptors(clazz));
property.setChildren(children);
}
} else if (property.getType() == BeanPropertyType.DB_REF) {
// 当存在db-ref时解析为动态数据源
RestBean restBean = clazz.getAnnotation(RestBean.class);
String uri = restBean.value();
Map<String, Object> props = new HashMap<>();
props.put("uri", uri);
property.setProps(props);
}
return property;
}

View File

@ -1,11 +1,15 @@
package com.flyfish.framework.beans.meta;
import com.flyfish.framework.beans.annotations.RestBean;
import com.flyfish.framework.domain.base.Domain;
import lombok.Getter;
import java.beans.PropertyDescriptor;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.function.Predicate;
/**
* bean属性的类型
@ -22,20 +26,34 @@ public enum BeanPropertyType {
DATE("Date", Date.class),
ENUM("Enum", Enum.class),
LIST("Array", Collection.class),
DB_REF("Ref", descriptor -> {
Class<?> clazz = descriptor.getPropertyType();
return Domain.class.isAssignableFrom(clazz) && clazz.isAnnotationPresent(RestBean.class);
}),
OBJECT("Object", Object.class);
BeanPropertyType(String name, Class<?> ...classes) {
private final Predicate<PropertyDescriptor> acceptor;
BeanPropertyType(String name, Class<?>... classes) {
this.name = name;
this.classes = Arrays.asList(classes);
this.acceptor = null;
}
private final String name;
private final List<Class<?>> classes;
public static BeanPropertyType of(Class<?> clazz) {
BeanPropertyType(String name, Predicate<PropertyDescriptor> predicate) {
this.name = name;
this.classes = null;
this.acceptor = predicate;
}
public static BeanPropertyType of(PropertyDescriptor descriptor) {
for (BeanPropertyType type : values()) {
if (type.classes.stream().anyMatch(item -> item.isAssignableFrom(clazz))) {
if (null != type.classes && type.classes.stream().anyMatch(item -> item.isAssignableFrom(descriptor.getPropertyType())) ||
null != type.acceptor && type.acceptor.test(descriptor)) {
return type;
}
}

View File

@ -0,0 +1,13 @@
package com.flyfish.framework.beans.meta;
import java.lang.annotation.*;
/**
* 标记需要解析的子bean
* @author wangyu
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SubBean {
}