mirror of
https://github.com/hs-web/hsweb-framework.git
synced 2026-06-20 18:56:01 +08:00
优化实体属性复制
This commit is contained in:
@@ -21,7 +21,6 @@ package org.hswebframework.web.commons.entity;
|
||||
|
||||
import org.hswebframework.web.id.IDGenerator;
|
||||
import org.hswebframwork.utils.RandomUtil;
|
||||
import org.hswebframwork.utils.StringUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
@@ -52,11 +51,6 @@ public interface TreeSupportEntity<PK> extends GenericEntity<PK> {
|
||||
|
||||
void setLevel(Integer level);
|
||||
|
||||
default void setLevelFromPath() {
|
||||
if (getPath() != null)
|
||||
setLevel(getPath().split("-").length);
|
||||
}
|
||||
|
||||
<T extends TreeSupportEntity<PK>> List<T> getChildren();
|
||||
|
||||
/**
|
||||
@@ -85,7 +79,8 @@ public interface TreeSupportEntity<PK> extends GenericEntity<PK> {
|
||||
List<T> children = parent.getChildren();
|
||||
if (parent.getPath() == null) {
|
||||
parent.setPath(RandomUtil.randomChar(4));
|
||||
parent.setLevelFromPath();
|
||||
if (parent.getPath() != null)
|
||||
parent.setLevel(parent.getPath().split("-").length);
|
||||
}
|
||||
if (children != null) {
|
||||
PK pid = parent.getId();
|
||||
@@ -104,7 +99,7 @@ public interface TreeSupportEntity<PK> extends GenericEntity<PK> {
|
||||
}
|
||||
child.setParentId(pid);
|
||||
child.setPath(parent.getPath() + "-" + RandomUtil.randomChar(4));
|
||||
child.setLevelFromPath();
|
||||
child.setLevel(child.getPath().split("-").length);
|
||||
target.add(child);
|
||||
expandTree2List(child, target, idGenerator);
|
||||
}
|
||||
|
||||
@@ -18,23 +18,27 @@
|
||||
|
||||
package org.hswebframework.web.commons.entity.factory;
|
||||
|
||||
import org.apache.commons.beanutils.BeanUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.hswebframework.web.NotFoundException;
|
||||
import org.hswebframwork.utils.ClassUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* @author zhouhao
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class MapperEntityFactory implements EntityFactory {
|
||||
private Map<Class, Mapper> realTypeMapper = new HashMap<>();
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
private Map<Class, Mapper> realTypeMapper = new HashMap<>();
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
private Map<String, PropertyCopier> copierCache = new HashMap<>();
|
||||
|
||||
public MapperEntityFactory() {
|
||||
}
|
||||
@@ -48,45 +52,74 @@ public class MapperEntityFactory implements EntityFactory {
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapperEntityFactory addCopier(PropertyCopier copier) {
|
||||
Class source = ClassUtils.getGenericType(copier.getClass(), 0);
|
||||
Class target = ClassUtils.getGenericType(copier.getClass(), 1);
|
||||
if (source == null || source == Object.class) {
|
||||
throw new UnsupportedOperationException("generic type " + source + " not support");
|
||||
}
|
||||
if (target == null || target == Object.class) {
|
||||
throw new UnsupportedOperationException("generic type " + target + " not support");
|
||||
}
|
||||
addCopier(source, target, copier);
|
||||
return this;
|
||||
}
|
||||
|
||||
public <S, T> MapperEntityFactory addCopier(Class<S> source, Class<T> target, PropertyCopier<S, T> copier) {
|
||||
copierCache.put(getCopierCacheKey(source, target), copier);
|
||||
return this;
|
||||
}
|
||||
|
||||
private String getCopierCacheKey(Class source, Class target) {
|
||||
return source.getName().concat("->").concat(target.getName());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, T> T copyProperties(S source, T target) {
|
||||
Objects.requireNonNull(source);
|
||||
Objects.requireNonNull(target);
|
||||
try {
|
||||
// TODO: 17-3-30 应该设计为可自定义
|
||||
BeanUtils.copyProperties(target, source);
|
||||
PropertyCopier<S, T> copier = copierCache.<S, T>get(getCopierCacheKey(source.getClass(), target.getClass()));
|
||||
if (null != copier) return copier.copyProperties(source, target);
|
||||
|
||||
return JSON.parseObject(JSON.toJSONString(source), (Class<T>) target.getClass());
|
||||
} catch (Exception e) {
|
||||
logger.warn("copy properties error", e);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
protected <T> Mapper<T> initCache(Class<T> beanClass) {
|
||||
Mapper<T> mapper = null;
|
||||
Class<T> realType = null;
|
||||
if (!Modifier.isInterface(beanClass.getModifiers()) && !Modifier.isAbstract(beanClass.getModifiers())) {
|
||||
realType = beanClass;
|
||||
}
|
||||
//尝试使用 Simple类,如: package.SimpleUserBean
|
||||
if (realType == null) {
|
||||
String simpleClassName = beanClass.getPackage().getName().concat(".Simple").concat(beanClass.getSimpleName());
|
||||
try {
|
||||
realType = (Class<T>) Class.forName(simpleClassName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new NotFoundException(e.getMessage());
|
||||
}
|
||||
}
|
||||
if (realType != null) {
|
||||
mapper = new Mapper<>(realType, new DefaultInstanceGetter(realType));
|
||||
realTypeMapper.put(beanClass, mapper);
|
||||
}
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T newInstance(Class<T> beanClass) {
|
||||
if (beanClass == null) return null;
|
||||
Mapper<T> mapper = realTypeMapper.get(beanClass);
|
||||
if (mapper != null) return mapper.getInstanceGetter().get();
|
||||
synchronized (beanClass) {
|
||||
mapper = realTypeMapper.get(beanClass);
|
||||
if (mapper != null) return mapper.getInstanceGetter().get();
|
||||
Class<T> realType = null;
|
||||
if (!Modifier.isInterface(beanClass.getModifiers()) && !Modifier.isAbstract(beanClass.getModifiers())) {
|
||||
realType = beanClass;
|
||||
}
|
||||
//尝试使用 Simple类,如: package.SimpleUserBean
|
||||
if (realType == null) {
|
||||
String simpleClassName = beanClass.getPackage().getName().concat(".Simple").concat(beanClass.getSimpleName());
|
||||
try {
|
||||
realType = (Class<T>) Class.forName(simpleClassName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new NotFoundException(e.getMessage());
|
||||
}
|
||||
}
|
||||
if (realType != null) {
|
||||
mapper = new Mapper<>(realType, new DefaultInstanceGetter(realType));
|
||||
realTypeMapper.put(beanClass, mapper);
|
||||
return mapper.getInstanceGetter().get();
|
||||
}
|
||||
}
|
||||
mapper = initCache(beanClass);
|
||||
if (mapper != null) return mapper.getInstanceGetter().get();
|
||||
|
||||
throw new NotFoundException("can't create instance for " + beanClass);
|
||||
}
|
||||
|
||||
@@ -97,7 +130,10 @@ public class MapperEntityFactory implements EntityFactory {
|
||||
if (null != mapper) {
|
||||
return mapper.getTarget();
|
||||
}
|
||||
return null;
|
||||
mapper = initCache(beanClass);
|
||||
if (mapper != null)
|
||||
return mapper.getTarget();
|
||||
return beanClass;
|
||||
}
|
||||
|
||||
public static class Mapper<T> {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.hswebframework.web.commons.entity.factory;
|
||||
|
||||
/**
|
||||
* 属性复制接口,用于自定义属性复制
|
||||
*
|
||||
* @author zhouhao
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface PropertyCopier<S, T> {
|
||||
T copyProperties(S source, T target);
|
||||
}
|
||||
Reference in New Issue
Block a user