mirror of
https://github.com/chillzhuang/blade-tool
synced 2024-12-12 20:29:27 +08:00
🐛 修复 BUG
This commit is contained in:
parent
226151bee3
commit
bac9c5e02e
@ -100,10 +100,6 @@ public class LogApi implements Serializable {
|
|||||||
* 执行时间
|
* 执行时间
|
||||||
*/
|
*/
|
||||||
private String time;
|
private String time;
|
||||||
/**
|
|
||||||
* 异常信息
|
|
||||||
*/
|
|
||||||
private String exception;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建人
|
* 创建人
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springblade.core.log.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LogApi视图实体类
|
||||||
|
*
|
||||||
|
* @author smallchill
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class LogApiVo extends LogApi {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String strId;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springblade.core.log.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LogError视图实体类
|
||||||
|
*
|
||||||
|
* @author smallchill
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class LogErrorVo extends LogError {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String strId;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springblade.core.log.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LogUsual视图实体类
|
||||||
|
*
|
||||||
|
* @author smallchill
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class LogUsualVo extends LogUsual {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String strId;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,184 @@
|
|||||||
|
package org.springblade.core.tool.support;
|
||||||
|
|
||||||
|
import org.springblade.core.tool.utils.BeanUtil;
|
||||||
|
import org.springframework.asm.ClassVisitor;
|
||||||
|
import org.springframework.asm.Type;
|
||||||
|
import org.springframework.cglib.core.*;
|
||||||
|
|
||||||
|
import java.beans.PropertyDescriptor;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* spring cglib 魔改
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 1. 支持链式 bean
|
||||||
|
* 2. 自定义的 BeanCopier 解决 spring boot 和 cglib ClassLoader classLoader 不一致的问题
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author L.cm
|
||||||
|
*/
|
||||||
|
public abstract class BladeBeanCopier {
|
||||||
|
private static final BeanCopierKey KEY_FACTORY = (BeanCopierKey) KeyFactory.create(BeanCopierKey.class);
|
||||||
|
private static final Type CONVERTER = TypeUtils.parseType("org.springframework.cglib.core.Converter");
|
||||||
|
private static final Type BEAN_COPIER = TypeUtils.parseType(BladeBeanCopier.class.getName());
|
||||||
|
private static final Signature COPY = new Signature("copy", Type.VOID_TYPE, new Type[]{Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER});
|
||||||
|
private static final Signature CONVERT = TypeUtils.parseSignature("Object convert(Object, Class, Object)");
|
||||||
|
|
||||||
|
interface BeanCopierKey {
|
||||||
|
Object newInstance(String source, String target, boolean useConverter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BladeBeanCopier create(Class source, Class target, boolean useConverter) {
|
||||||
|
return BladeBeanCopier.create(source, target, null, useConverter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BladeBeanCopier create(Class source, Class target, ClassLoader classLoader, boolean useConverter) {
|
||||||
|
Generator gen;
|
||||||
|
if (classLoader == null) {
|
||||||
|
gen = new Generator();
|
||||||
|
} else {
|
||||||
|
gen = new Generator(classLoader);
|
||||||
|
}
|
||||||
|
gen.setSource(source);
|
||||||
|
gen.setTarget(target);
|
||||||
|
gen.setUseConverter(useConverter);
|
||||||
|
return gen.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public void copy(Object from, Object to, Converter converter);
|
||||||
|
|
||||||
|
public static class Generator extends AbstractClassGenerator {
|
||||||
|
private static final Source SOURCE = new Source(BladeBeanCopier.class.getName());
|
||||||
|
private final ClassLoader classLoader;
|
||||||
|
private Class source;
|
||||||
|
private Class target;
|
||||||
|
private boolean useConverter;
|
||||||
|
|
||||||
|
Generator() {
|
||||||
|
super(SOURCE);
|
||||||
|
this.classLoader = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Generator(ClassLoader classLoader) {
|
||||||
|
super(SOURCE);
|
||||||
|
this.classLoader = classLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSource(Class source) {
|
||||||
|
if (!Modifier.isPublic(source.getModifiers())) {
|
||||||
|
setNamePrefix(source.getName());
|
||||||
|
}
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTarget(Class target) {
|
||||||
|
if (!Modifier.isPublic(target.getModifiers())) {
|
||||||
|
setNamePrefix(target.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUseConverter(boolean useConverter) {
|
||||||
|
this.useConverter = useConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClassLoader getDefaultClassLoader() {
|
||||||
|
return target.getClassLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ProtectionDomain getProtectionDomain() {
|
||||||
|
return ReflectUtils.getProtectionDomain(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BladeBeanCopier create() {
|
||||||
|
Object key = KEY_FACTORY.newInstance(source.getName(), target.getName(), useConverter);
|
||||||
|
return (BladeBeanCopier) super.create(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateClass(ClassVisitor v) {
|
||||||
|
Type sourceType = Type.getType(source);
|
||||||
|
Type targetType = Type.getType(target);
|
||||||
|
ClassEmitter ce = new ClassEmitter(v);
|
||||||
|
ce.begin_class(Constants.V1_2,
|
||||||
|
Constants.ACC_PUBLIC,
|
||||||
|
getClassName(),
|
||||||
|
BEAN_COPIER,
|
||||||
|
null,
|
||||||
|
Constants.SOURCE_FILE);
|
||||||
|
|
||||||
|
EmitUtils.null_constructor(ce);
|
||||||
|
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, COPY, null);
|
||||||
|
|
||||||
|
// 2018.12.27 by L.cm 支持链式 bean
|
||||||
|
PropertyDescriptor[] getters = BeanUtil.getBeanGetters(source);
|
||||||
|
PropertyDescriptor[] setters = BeanUtil.getBeanSetters(target);
|
||||||
|
Map<String, Object> names = new HashMap<>();
|
||||||
|
for (PropertyDescriptor getter : getters) {
|
||||||
|
names.put(getter.getName(), getter);
|
||||||
|
}
|
||||||
|
|
||||||
|
Local targetLocal = e.make_local();
|
||||||
|
Local sourceLocal = e.make_local();
|
||||||
|
e.load_arg(1);
|
||||||
|
e.checkcast(targetType);
|
||||||
|
e.store_local(targetLocal);
|
||||||
|
e.load_arg(0);
|
||||||
|
e.checkcast(sourceType);
|
||||||
|
e.store_local(sourceLocal);
|
||||||
|
|
||||||
|
for (int i = 0; i < setters.length; i++) {
|
||||||
|
PropertyDescriptor setter = setters[i];
|
||||||
|
PropertyDescriptor getter = (PropertyDescriptor) names.get(setter.getName());
|
||||||
|
if (getter != null) {
|
||||||
|
MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod());
|
||||||
|
MethodInfo write = ReflectUtils.getMethodInfo(setter.getWriteMethod());
|
||||||
|
if (useConverter) {
|
||||||
|
Type setterType = write.getSignature().getArgumentTypes()[0];
|
||||||
|
e.load_local(targetLocal);
|
||||||
|
e.load_arg(2);
|
||||||
|
e.load_local(sourceLocal);
|
||||||
|
e.invoke(read);
|
||||||
|
e.box(read.getSignature().getReturnType());
|
||||||
|
EmitUtils.load_class(e, setterType);
|
||||||
|
e.push(write.getSignature().getName());
|
||||||
|
e.invoke_interface(CONVERTER, CONVERT);
|
||||||
|
e.unbox_or_zero(setterType);
|
||||||
|
e.invoke(write);
|
||||||
|
} else if (compatible(getter, setter)) {
|
||||||
|
// 2018.12.27 by L.cm 支持链式 bean
|
||||||
|
e.load_local(targetLocal);
|
||||||
|
e.load_local(sourceLocal);
|
||||||
|
e.invoke(read);
|
||||||
|
e.invoke(write);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.return_value();
|
||||||
|
e.end_method();
|
||||||
|
ce.end_class();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean compatible(PropertyDescriptor getter, PropertyDescriptor setter) {
|
||||||
|
// TODO: allow automatic widening conversions?
|
||||||
|
return setter.getPropertyType().isAssignableFrom(getter.getPropertyType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object firstInstance(Class type) {
|
||||||
|
return ReflectUtils.newInstance(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object nextInstance(Object instance) {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,12 +17,16 @@ package org.springblade.core.tool.utils;
|
|||||||
|
|
||||||
|
|
||||||
import org.springblade.core.tool.support.BeanProperty;
|
import org.springblade.core.tool.support.BeanProperty;
|
||||||
|
import org.springblade.core.tool.support.BladeBeanCopier;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.cglib.beans.BeanCopier;
|
|
||||||
import org.springframework.cglib.beans.BeanGenerator;
|
import org.springframework.cglib.beans.BeanGenerator;
|
||||||
import org.springframework.cglib.beans.BeanMap;
|
import org.springframework.cglib.beans.BeanMap;
|
||||||
|
import org.springframework.cglib.core.CodeGenerationException;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import java.beans.PropertyDescriptor;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,7 +109,7 @@ public class BeanUtil extends org.springframework.beans.BeanUtils {
|
|||||||
* @return T
|
* @return T
|
||||||
*/
|
*/
|
||||||
public static <T> T copy(Object source, Class<T> clazz) {
|
public static <T> T copy(Object source, Class<T> clazz) {
|
||||||
BeanCopier copier = BeanCopier.create(source.getClass(), clazz, false);
|
BladeBeanCopier copier = BladeBeanCopier.create(source.getClass(), clazz, false);
|
||||||
|
|
||||||
T to = newInstance(clazz);
|
T to = newInstance(clazz);
|
||||||
copier.copy(source, to, null);
|
copier.copy(source, to, null);
|
||||||
@ -121,7 +125,7 @@ public class BeanUtil extends org.springframework.beans.BeanUtils {
|
|||||||
* @param targetBean 需要赋值的对象
|
* @param targetBean 需要赋值的对象
|
||||||
*/
|
*/
|
||||||
public static void copy(Object source, Object targetBean) {
|
public static void copy(Object source, Object targetBean) {
|
||||||
BeanCopier copier = BeanCopier
|
BladeBeanCopier copier = BladeBeanCopier
|
||||||
.create(source.getClass(), targetBean.getClass(), false);
|
.create(source.getClass(), targetBean.getClass(), false);
|
||||||
|
|
||||||
copier.copy(source, targetBean, null);
|
copier.copy(source, targetBean, null);
|
||||||
@ -197,4 +201,43 @@ public class BeanUtil extends org.springframework.beans.BeanUtils {
|
|||||||
return generator.create();
|
return generator.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Bean 的所有 get方法
|
||||||
|
* @param type 类
|
||||||
|
* @return PropertyDescriptor数组
|
||||||
|
*/
|
||||||
|
public static PropertyDescriptor[] getBeanGetters(Class type) {
|
||||||
|
return getPropertiesHelper(type, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Bean 的所有 set方法
|
||||||
|
* @param type 类
|
||||||
|
* @return PropertyDescriptor数组
|
||||||
|
*/
|
||||||
|
public static PropertyDescriptor[] getBeanSetters(Class type) {
|
||||||
|
return getPropertiesHelper(type, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PropertyDescriptor[] getPropertiesHelper(Class type, boolean read, boolean write) {
|
||||||
|
try {
|
||||||
|
PropertyDescriptor[] all = BeanUtil.getPropertyDescriptors(type);
|
||||||
|
if (read && write) {
|
||||||
|
return all;
|
||||||
|
} else {
|
||||||
|
List<PropertyDescriptor> properties = new ArrayList<>(all.length);
|
||||||
|
for (PropertyDescriptor pd : all) {
|
||||||
|
if (read && pd.getReadMethod() != null) {
|
||||||
|
properties.add(pd);
|
||||||
|
} else if (write && pd.getWriteMethod() != null) {
|
||||||
|
properties.add(pd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return properties.toArray(new PropertyDescriptor[0]);
|
||||||
|
}
|
||||||
|
} catch (BeansException ex) {
|
||||||
|
throw new CodeGenerationException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user