mirror of
https://github.com/hs-web/hsweb-framework.git
synced 2026-09-03 06:35:25 +08:00
refactor: 优化对拓展实体支持
This commit is contained in:
@@ -19,6 +19,14 @@ public final class EntityFactoryHolder {
|
||||
return FACTORY;
|
||||
}
|
||||
|
||||
|
||||
public static <T> Class<T> getMappedType(Class<T> type) {
|
||||
if (FACTORY != null) {
|
||||
return FACTORY.getInstanceType(type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static <T> T newInstance(Class<T> type,
|
||||
Supplier<T> mapper) {
|
||||
if (FACTORY != null) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.hswebframework.ezorm.rdb.executor.wrapper.ColumnWrapperContext;
|
||||
import org.hswebframework.ezorm.rdb.executor.wrapper.MapResultWrapper;
|
||||
import org.hswebframework.ezorm.rdb.executor.wrapper.ResultWrapper;
|
||||
import org.hswebframework.ezorm.rdb.executor.wrapper.ResultWrappers;
|
||||
import org.hswebframework.ezorm.rdb.mapping.EntityPropertyDescriptor;
|
||||
import org.hswebframework.ezorm.rdb.mapping.defaults.record.DefaultRecord;
|
||||
import org.hswebframework.ezorm.rdb.mapping.defaults.record.Record;
|
||||
import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
|
||||
@@ -30,6 +31,8 @@ import org.hswebframework.ezorm.rdb.operator.dml.SelectColumnSupplier;
|
||||
import org.hswebframework.ezorm.rdb.operator.dml.query.BuildParameterQueryOperator;
|
||||
import org.hswebframework.ezorm.rdb.operator.dml.query.Selects;
|
||||
import org.hswebframework.ezorm.rdb.operator.dml.query.SortOrder;
|
||||
import org.hswebframework.ezorm.rdb.utils.PropertyUtils;
|
||||
import org.hswebframework.web.api.crud.entity.EntityFactoryHolder;
|
||||
import org.hswebframework.web.api.crud.entity.PagerResult;
|
||||
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
|
||||
import org.hswebframework.web.bean.FastBeanCopier;
|
||||
@@ -367,6 +370,9 @@ public class DefaultQueryHelper implements QueryHelper {
|
||||
RDBColumnMetadata metadata = target.getColumn(column[1]).orElse(null);
|
||||
|
||||
if (metadata != null) {
|
||||
if(metadata.getFeature(EntityPropertyDescriptor.ID).isPresent()){
|
||||
return;
|
||||
}
|
||||
ObjectPropertyOperator operator = GlobalConfig.getPropertyOperator();
|
||||
if (targetProperty == null) {
|
||||
operator.setProperty(result, column[1], metadata.decode(sqlValue));
|
||||
@@ -510,7 +516,7 @@ public class DefaultQueryHelper implements QueryHelper {
|
||||
private Function<Flux<R>, Flux<R>> resultHandler = Function.identity();
|
||||
|
||||
public QuerySpec(Class<R> clazz, DefaultQueryHelper parent) {
|
||||
this.clazz = clazz;
|
||||
this.clazz = EntityFactoryHolder.getMappedType(clazz);
|
||||
this.parent = parent;
|
||||
logContext = Context.of(Logger.class, LoggerFactory.getLogger(clazz));
|
||||
}
|
||||
@@ -869,10 +875,15 @@ public class DefaultQueryHelper implements QueryHelper {
|
||||
return join(type, createJoinAlias(), JoinType.right, on);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public R newRowInstance0() {
|
||||
return clazz.getConstructor().newInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public R newRowInstance() {
|
||||
return clazz.newInstance();
|
||||
return EntityFactoryHolder.newInstance(clazz, this::newRowInstance0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,6 +3,9 @@ package org.hswebframework.web.crud.query;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.hswebframework.ezorm.core.FeatureId;
|
||||
import org.hswebframework.ezorm.core.FeatureType;
|
||||
import org.hswebframework.ezorm.core.meta.Feature;
|
||||
import org.hswebframework.ezorm.rdb.executor.SqlRequest;
|
||||
import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
|
||||
import org.hswebframework.ezorm.rdb.metadata.TableOrViewMetadata;
|
||||
@@ -129,7 +132,9 @@ public interface QueryAnalyzer {
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
class Column {
|
||||
class Column implements Feature {
|
||||
static final FeatureId<Column> FEATURE_ID = FeatureId.of("AnalyzedColumn");
|
||||
|
||||
//列名
|
||||
String name;
|
||||
//别名
|
||||
@@ -142,6 +147,16 @@ public interface QueryAnalyzer {
|
||||
public Column moveOwner(String owner) {
|
||||
return new Column(name, alias, owner, metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return FEATURE_ID.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureType getType() {
|
||||
return AnalyzerFeatureType.AnalyzedCol;
|
||||
}
|
||||
}
|
||||
|
||||
class SelectTable extends Table {
|
||||
@@ -176,4 +191,18 @@ public interface QueryAnalyzer {
|
||||
}
|
||||
|
||||
|
||||
enum AnalyzerFeatureType implements FeatureType {
|
||||
AnalyzedCol;
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.hswebframework.web.cache.supports;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.hswebframework.web.cache.ReactiveCache;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.CoreSubscriber;
|
||||
@@ -17,8 +18,10 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Slf4j
|
||||
public abstract class AbstractReactiveCache<E> implements ReactiveCache<E> {
|
||||
static Sinks.EmitFailureHandler emitFailureHandler = Sinks.EmitFailureHandler.busyLooping(Duration.ofSeconds(30));
|
||||
static final Sinks.EmitFailureHandler emitFailureHandler = Sinks.EmitFailureHandler.busyLooping(Duration.ofSeconds(30));
|
||||
|
||||
private final Map<Object, CacheLoader> cacheLoading = new ConcurrentHashMap<>();
|
||||
|
||||
protected static class CacheLoader extends MonoOperator<Object, Object> {
|
||||
@@ -53,25 +56,25 @@ public abstract class AbstractReactiveCache<E> implements ReactiveCache<E> {
|
||||
Mono<? extends Object> source = this.source;
|
||||
if (defaultValue != null) {
|
||||
source = source
|
||||
.switchIfEmpty((Mono) defaultValue
|
||||
.flatMap(val -> {
|
||||
return parent.putNow(key, val).thenReturn(val);
|
||||
}));
|
||||
.switchIfEmpty((Mono) defaultValue
|
||||
.flatMap(val -> {
|
||||
return parent.putNow(key, val).thenReturn(val);
|
||||
}));
|
||||
}
|
||||
loading = source.subscribe(
|
||||
val -> {
|
||||
complete();
|
||||
holder.emitValue(val, emitFailureHandler);
|
||||
},
|
||||
err -> {
|
||||
complete();
|
||||
holder.emitError(err, emitFailureHandler);
|
||||
},
|
||||
() -> {
|
||||
complete();
|
||||
holder.emitEmpty(emitFailureHandler);
|
||||
},
|
||||
Context.of(context));
|
||||
val -> {
|
||||
complete();
|
||||
holder.emitValue(val, emitFailureHandler);
|
||||
},
|
||||
err -> {
|
||||
complete();
|
||||
holder.emitError(err, emitFailureHandler);
|
||||
},
|
||||
() -> {
|
||||
complete();
|
||||
holder.emitEmpty(emitFailureHandler);
|
||||
},
|
||||
Context.of(context));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,42 +98,53 @@ public abstract class AbstractReactiveCache<E> implements ReactiveCache<E> {
|
||||
@Override
|
||||
@SuppressWarnings("all")
|
||||
public final Mono<E> getMono(Object key) {
|
||||
return (Mono<E>) cacheLoading.computeIfAbsent(key, _key -> new CacheLoader(this, _key, getNow(_key)));
|
||||
return (Mono<E>) cacheLoading
|
||||
.computeIfAbsent(key, _key -> new CacheLoader(this, _key, getNow(_key)))
|
||||
.onErrorResume(err -> handleLoaderError(key, err));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("all")
|
||||
public final Mono<E> getMono(Object key, Supplier<Mono<E>> loader) {
|
||||
|
||||
return Mono.deferContextual(ctx -> {
|
||||
CacheLoader cacheLoader = cacheLoading.compute(key, (_key, old) -> {
|
||||
CacheLoader cl = new CacheLoader(this, _key, getNow(_key));
|
||||
cl.defaultValue(loader.get(), ctx);
|
||||
return cl;
|
||||
});
|
||||
return (Mono<E>) cacheLoader;
|
||||
});
|
||||
return Mono
|
||||
.deferContextual(ctx -> {
|
||||
CacheLoader cacheLoader = cacheLoading.compute(key, (_key, old) -> {
|
||||
CacheLoader cl = new CacheLoader(this, _key, getNow(_key));
|
||||
cl.defaultValue(loader.get(), ctx);
|
||||
return cl;
|
||||
});
|
||||
return (Mono<E>) cacheLoader;
|
||||
})
|
||||
.onErrorResume(err -> handleLoaderError(key, err));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final Flux<E> getFlux(Object key) {
|
||||
return (cacheLoading.computeIfAbsent(key, _key -> new CacheLoader(this, _key, getNow(_key))))
|
||||
.flatMapIterable(e -> ((List<E>) e));
|
||||
.flatMapIterable(e -> ((List<E>) e))
|
||||
.onErrorResume(err -> handleLoaderError(key, err));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Flux<E> getFlux(Object key, Supplier<Flux<E>> loader) {
|
||||
return Flux.deferContextual(ctx -> {
|
||||
CacheLoader cacheLoader = cacheLoading.compute(key, (_key, old) -> {
|
||||
CacheLoader cl = new CacheLoader(this, _key, getNow(_key));
|
||||
cl.defaultValue(loader.get().collectList(), ctx);
|
||||
return cl;
|
||||
});
|
||||
return cacheLoader.flatMapIterable(e -> ((List<E>) e));
|
||||
});
|
||||
CacheLoader cacheLoader = cacheLoading.compute(key, (_key, old) -> {
|
||||
CacheLoader cl = new CacheLoader(this, _key, getNow(_key));
|
||||
cl.defaultValue(loader.get().collectList(), ctx);
|
||||
return cl;
|
||||
});
|
||||
return cacheLoader.flatMapIterable(e -> ((List<E>) e));
|
||||
})
|
||||
.onErrorResume(err -> handleLoaderError(key, err));
|
||||
}
|
||||
|
||||
protected Mono<E> handleLoaderError(Object key, Throwable err) {
|
||||
log.warn("load cache error,key:{},evict it.", key, err);
|
||||
return evict(key)
|
||||
.then(Mono.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Mono<Void> put(Object key, Publisher<E> data) {
|
||||
|
||||
@@ -137,5 +137,10 @@
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hswebframework</groupId>
|
||||
<artifactId>hsweb-easy-orm-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -3,7 +3,12 @@ package org.hswebframework.web.bean;
|
||||
import lombok.Getter;
|
||||
import org.hswebframework.web.dict.EnumDict;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
public class ClassDescription {
|
||||
@@ -17,6 +22,7 @@ public class ClassDescription {
|
||||
private final boolean number;
|
||||
|
||||
private final Object[] enums;
|
||||
private final Map<String, Field> fields;
|
||||
|
||||
public ClassDescription(Class<?> type) {
|
||||
this.type = type;
|
||||
@@ -31,6 +37,9 @@ public class ClassDescription {
|
||||
} else {
|
||||
enums = null;
|
||||
}
|
||||
fields = Arrays
|
||||
.stream(type.getDeclaredFields())
|
||||
.collect(Collectors.toMap(Field::getName, f -> f, (a, b) -> b));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.hswebframework.web.bean;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.hswebframework.ezorm.core.Extensible;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@AllArgsConstructor
|
||||
class ExtensibleToMapCopier implements Copier {
|
||||
|
||||
private final Copier copier;
|
||||
|
||||
@Override
|
||||
public void copy(Object source, Object target, Set<String> ignore, Converter converter) {
|
||||
copier.copy(source, target, ignore, converter);
|
||||
ExtensibleUtils.copyToMap((Extensible) target, ignore, (Map<String, Object>) source);
|
||||
//移除map中的extensions
|
||||
((Map<?, ?>) source).remove("extensions");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.hswebframework.web.bean;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.hswebframework.ezorm.core.Extensible;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ExtensibleUtils {
|
||||
|
||||
public static void copyFromMap(Map<String, Object> source,
|
||||
Set<String> ignore,
|
||||
Extensible target) {
|
||||
ClassDescription def = ClassDescriptions.getDescription(target.getClass());
|
||||
|
||||
for (Map.Entry<String, Object> entry : source.entrySet()) {
|
||||
//只copy没有定义的数据
|
||||
if (!ignore.contains(entry.getKey()) && !def.getFields().containsKey(entry.getKey())) {
|
||||
target.setExtension(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void copyToMap(Extensible target,
|
||||
Set<String> ignore,
|
||||
Map<String, Object> source) {
|
||||
if (CollectionUtils.isNotEmpty(ignore)) {
|
||||
source.putAll(
|
||||
Maps.filterKeys(target.extensions(), key -> !ignore.contains(key))
|
||||
);
|
||||
} else {
|
||||
source.putAll(
|
||||
target.extensions()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.beanutils.BeanUtilsBean;
|
||||
import org.apache.commons.beanutils.ConvertUtilsBean;
|
||||
import org.apache.commons.beanutils.PropertyUtilsBean;
|
||||
import org.hswebframework.ezorm.core.Extensible;
|
||||
import org.hswebframework.utils.time.DateFormatter;
|
||||
import org.hswebframework.web.dict.EnumDict;
|
||||
import org.hswebframework.web.proxy.Proxy;
|
||||
@@ -179,6 +180,11 @@ public final class FastBeanCopier {
|
||||
if (tartName.startsWith("package ")) {
|
||||
tartName = tartName.substring("package ".length());
|
||||
}
|
||||
boolean targetIsExtensible = Extensible.class.isAssignableFrom(target);
|
||||
boolean sourceIsExtensible = Extensible.class.isAssignableFrom(source);
|
||||
boolean targetIsMap = Map.class.isAssignableFrom(target);
|
||||
boolean sourceIsMap = Map.class.isAssignableFrom(source);
|
||||
|
||||
String method = "public void copy(Object s, Object t, java.util.Set ignore, " +
|
||||
"org.hswebframework.web.bean.Converter converter){\n" +
|
||||
"try{\n\t" +
|
||||
@@ -194,7 +200,14 @@ public final class FastBeanCopier {
|
||||
Proxy<Copier> proxy = Proxy
|
||||
.create(Copier.class, new Class[]{source, target})
|
||||
.addMethod(method);
|
||||
return proxy.newInstance();
|
||||
Copier copier = proxy.newInstance();
|
||||
if (targetIsExtensible && sourceIsMap) {
|
||||
copier = new ExtensibleToMapCopier(copier);
|
||||
}
|
||||
if (sourceIsMap && targetIsExtensible) {
|
||||
copier = new MapToExtensibleCopier(copier);
|
||||
}
|
||||
return copier;
|
||||
} catch (Exception e) {
|
||||
log.error("创建bean copy 代理对象失败:\n{}", method, e);
|
||||
throw new UnsupportedOperationException(e.getMessage(), e);
|
||||
@@ -203,8 +216,10 @@ public final class FastBeanCopier {
|
||||
|
||||
private static Map<String, ClassProperty> createProperty(Class<?> type) {
|
||||
|
||||
List<String> fieldNames = Arrays.stream(type.getDeclaredFields())
|
||||
.map(Field::getName).collect(Collectors.toList());
|
||||
List<String> fieldNames = Arrays
|
||||
.stream(type.getDeclaredFields())
|
||||
.map(Field::getName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return Stream.of(propertyUtils.getPropertyDescriptors(type))
|
||||
.filter(property -> !property
|
||||
@@ -218,8 +233,11 @@ public final class FastBeanCopier {
|
||||
}
|
||||
|
||||
private static Map<String, ClassProperty> createMapProperty(Map<String, ClassProperty> template) {
|
||||
return template.values().stream().map(classProperty -> new MapClassProperty(classProperty.name))
|
||||
.collect(Collectors.toMap(ClassProperty::getName, Function.identity(), (k, k2) -> k, LinkedHashMap::new));
|
||||
return template
|
||||
.values()
|
||||
.stream()
|
||||
.map(classProperty -> new MapClassProperty(classProperty.name))
|
||||
.collect(Collectors.toMap(ClassProperty::getName, Function.identity(), (k, k2) -> k, LinkedHashMap::new));
|
||||
}
|
||||
|
||||
private static String createCopierCode(Class<?> source, Class<?> target) {
|
||||
@@ -227,19 +245,20 @@ public final class FastBeanCopier {
|
||||
|
||||
Map<String, ClassProperty> targetProperties = null;
|
||||
|
||||
boolean targetIsExtensible = Extensible.class.isAssignableFrom(target);
|
||||
boolean sourceIsExtensible = Extensible.class.isAssignableFrom(source);
|
||||
boolean targetIsMap = Map.class.isAssignableFrom(target);
|
||||
boolean sourceIsMap = Map.class.isAssignableFrom(source);
|
||||
//源类型为Map
|
||||
if (Map.class.isAssignableFrom(source)) {
|
||||
if (!Map.class.isAssignableFrom(target)) {
|
||||
if (sourceIsMap) {
|
||||
if (!targetIsMap) {
|
||||
targetProperties = createProperty(target);
|
||||
sourceProperties = createMapProperty(targetProperties);
|
||||
|
||||
}
|
||||
} else if (Map.class.isAssignableFrom(target)) {
|
||||
if (!Map.class.isAssignableFrom(source)) {
|
||||
sourceProperties = createProperty(source);
|
||||
targetProperties = createMapProperty(sourceProperties);
|
||||
|
||||
}
|
||||
} else if (targetIsMap) {
|
||||
sourceProperties = createProperty(source);
|
||||
targetProperties = createMapProperty(sourceProperties);
|
||||
} else {
|
||||
targetProperties = createProperty(target);
|
||||
sourceProperties = createProperty(source);
|
||||
@@ -252,6 +271,21 @@ public final class FastBeanCopier {
|
||||
for (ClassProperty sourceProperty : sourceProperties.values()) {
|
||||
ClassProperty targetProperty = targetProperties.get(sourceProperty.getName());
|
||||
if (targetProperty == null) {
|
||||
//复制到拓展对象
|
||||
if (targetIsExtensible && !sourceIsExtensible) {
|
||||
code.append("if(!ignore.contains(\"").append(sourceProperty.getName()).append("\")){\n\t");
|
||||
if (!sourceProperty.isPrimitive()) {
|
||||
code.append("if($$__source.").append(sourceProperty.getReadMethod()).append("!=null){\n");
|
||||
}
|
||||
code.append("\t\t((org.hswebframework.ezorm.core.Extensible)$$__target).setExtension(")
|
||||
.append("\"").append(sourceProperty.name).append("\",")
|
||||
.append("$$__source.").append(sourceProperty.getReadMethod())
|
||||
.append(");");
|
||||
if (!sourceProperty.isPrimitive()) {
|
||||
code.append("\n\t}");
|
||||
}
|
||||
code.append("\n}\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
code.append("if(!ignore.contains(\"").append(sourceProperty.getName()).append("\")){\n\t");
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.hswebframework.web.bean;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.hswebframework.ezorm.core.Extensible;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@AllArgsConstructor
|
||||
class MapToExtensibleCopier implements Copier {
|
||||
|
||||
private final Copier copier;
|
||||
|
||||
@Override
|
||||
public void copy(Object source, Object target, Set<String> ignore, Converter converter) {
|
||||
copier.copy(source, target, ignore, converter);
|
||||
|
||||
ExtensibleUtils.copyFromMap((Map<String, Object>) source, ignore, (Extensible) target);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import com.google.common.collect.ImmutableMap;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.SneakyThrows;
|
||||
import org.hswebframework.ezorm.core.DefaultExtensible;
|
||||
import org.hswebframework.ezorm.core.Extensible;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -23,6 +25,54 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
*/
|
||||
public class FastBeanCopierTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testExtensible() {
|
||||
Source source = new Source();
|
||||
source.setName("test");
|
||||
source.setAge(123);
|
||||
source.setColor(Color.RED);
|
||||
ExtensibleEntity e = FastBeanCopier.copy(source, new ExtensibleEntity());
|
||||
|
||||
Assert.assertEquals(source.getName(), e.getName());
|
||||
Assert.assertEquals(source.getAge(), e.getExtension("age"));
|
||||
Assert.assertEquals(source.getColor(), e.getExtension("color"));
|
||||
|
||||
Map<String, Object> map = FastBeanCopier.copy(e, new HashMap<>());
|
||||
System.out.println(map);
|
||||
|
||||
ExtensibleEntity t = FastBeanCopier.copy(map, new ExtensibleEntity());
|
||||
Assert.assertEquals(e.getName(), t.getName());
|
||||
|
||||
System.out.println(e.extensions());
|
||||
System.out.println(t.extensions());
|
||||
Assert.assertEquals(e.extensions(), t.extensions());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapToExtensible() {
|
||||
Source source = new Source();
|
||||
source.setName("test");
|
||||
source.setAge(123);
|
||||
source.setColor(Color.RED);
|
||||
Map<String, Object> map = FastBeanCopier.copy(source, new HashMap<>());
|
||||
ExtensibleEntity e = FastBeanCopier.copy(map, new ExtensibleEntity());
|
||||
Assert.assertEquals(source.getName(), e.getName());
|
||||
Assert.assertEquals(source.getAge(), e.getExtension("age"));
|
||||
Assert.assertEquals(source.getColor(), e.getExtension("color"));
|
||||
}
|
||||
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class ExtensibleEntity extends DefaultExtensible {
|
||||
|
||||
private String name;
|
||||
|
||||
private boolean boy2;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws InvocationTargetException, IllegalAccessException {
|
||||
Source source = new Source();
|
||||
@@ -68,7 +118,7 @@ public class FastBeanCopierTest {
|
||||
@Test
|
||||
public void testMapList() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("templates", new HashMap() {
|
||||
data.put("templates", new HashMap() {
|
||||
{
|
||||
put("0", Collections.singletonMap("name", "test"));
|
||||
put("1", Collections.singletonMap("name", "test"));
|
||||
@@ -80,7 +130,7 @@ public class FastBeanCopierTest {
|
||||
Assert.assertNotNull(config);
|
||||
Assert.assertNotNull(config.templates);
|
||||
System.out.println(config.templates);
|
||||
Assert.assertEquals(2,config.templates.size());
|
||||
Assert.assertEquals(2, config.templates.size());
|
||||
|
||||
|
||||
}
|
||||
@@ -98,7 +148,7 @@ public class FastBeanCopierTest {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "name:"+name;
|
||||
return "name:" + name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,8 +182,8 @@ public class FastBeanCopierTest {
|
||||
|
||||
System.out.println(clazz);
|
||||
URLClassLoader loader = new URLClassLoader(new URL[]{
|
||||
clazz
|
||||
}, ClassUtils.getDefaultClassLoader()){
|
||||
clazz
|
||||
}, ClassUtils.getDefaultClassLoader()) {
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||
try {
|
||||
@@ -174,13 +224,13 @@ public class FastBeanCopierTest {
|
||||
Assert.assertNotSame(sourceClass, Source.class);
|
||||
|
||||
Object source = sourceClass.newInstance();
|
||||
FastBeanCopier.copy(Collections.singletonMap("name","测试"),source);
|
||||
FastBeanCopier.copy(Collections.singletonMap("name", "测试"), source);
|
||||
|
||||
Map<String,Object> map = FastBeanCopier.copy(source,new HashMap<>());
|
||||
Map<String, Object> map = FastBeanCopier.copy(source, new HashMap<>());
|
||||
System.out.println(map);
|
||||
|
||||
loader.close();
|
||||
map = FastBeanCopier.copy(source,new HashMap<>());
|
||||
map = FastBeanCopier.copy(source, new HashMap<>());
|
||||
|
||||
System.out.println(map);
|
||||
|
||||
@@ -193,17 +243,17 @@ public class FastBeanCopierTest {
|
||||
|
||||
ProxyTest test = (ProxyTest) Proxy.newProxyInstance(ClassUtils.getDefaultClassLoader(),
|
||||
new Class[]{ProxyTest.class}, (proxy, method, args) -> {
|
||||
if (method.getName().equals("getName")) {
|
||||
return "test";
|
||||
}
|
||||
|
||||
if (method.getName().equals("setName")) {
|
||||
reference.set(args[0]);
|
||||
return null;
|
||||
}
|
||||
if (method.getName().equals("getName")) {
|
||||
return "test";
|
||||
}
|
||||
|
||||
if (method.getName().equals("setName")) {
|
||||
reference.set(args[0]);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
Target source = new Target();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user