
cn.featherfly.common.bean.BeanDescriptor Maven / Gradle / Ivy
package cn.featherfly.common.bean;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.collections.map.ListOrderedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.featherfly.common.bean.matcher.BeanPropertyMatcher;
import cn.featherfly.common.lang.ClassUtils;
import cn.featherfly.common.lang.CollectionUtils;
import cn.featherfly.common.lang.LangUtils;
import cn.featherfly.common.lang.ServiceLoaderUtils;
/**
*
* java bean 的描述信息
*
*
* @author 钟冀
* @param
* 描述的类型
*/
public class BeanDescriptor {
private static final Logger LOGGER = LoggerFactory
.getLogger(BeanDescriptor.class);
private static final Map, BeanDescriptor>> BEAN_DESCRIPTORS = new ConcurrentHashMap, BeanDescriptor>>();
private static final BeanPropertyFactory FACTORY = ServiceLoaderUtils.load(
BeanPropertyFactory.class, new ReflectionBeanPropertyFactory());
// private static BeanPropertyFactory factory = new
// ReflectionBeanPropertyFactory();
//
// static {
// ServiceLoader serviceLoader =
// ServiceLoader.load(BeanPropertyFactory.class);
// List factorys = new
// ArrayList();
// for (BeanPropertyFactory factory : serviceLoader) {
// factorys.add(factory);
// }
// if (factorys.size() > 1) {
// throw new IllegalArgumentException("找到多个BeanPropertyFactory实现 -> " +
// factorys) ;
// }
// if (factorys.isEmpty()) {
// factory = new ReflectionBeanPropertyFactory();
// } else {
// factory = factorys.get(0);
// }
// }
// private Map beanProperties = new HashMap(0);
private ListOrderedMap beanProperties = new ListOrderedMap();
private Map typeGenericParams = new HashMap<>(0);
/**
* 句号(.)
*/
protected static final String DOT = ".";
/**
* @param type
* 类型
*/
protected BeanDescriptor(Class type) {
this.type = type;
initTypeGenericParam(this.type);
this.initFromField(this.type);
this.initFromMethod(this.type);
}
public void initTypeGenericParam(Class type) {
// 得到泛型父类
typeGenericParams = ClassUtils.getSuperClassGenricTypeMap(type);
}
// 从field开始初始化
private void initFromField(Class> parent) {
if (null == parent || parent == Object.class) {
return;
}
Field[] fields = parent.getDeclaredFields();
for (Field field : fields) {
Type genericType = typeGenericParams
.get(field.getGenericType().toString());
Class> fieldType = null;
// 判断类型定义的泛型参数
if (genericType == null) {
fieldType = field.getType();
} else {
fieldType = (Class>) genericType;
}
Method getter = ClassUtils.getGetter(field, this.type);
Method setter = ClassUtils.getSetter(field, this.type);
if (getter != null || setter != null) {
BeanProperty> prop = FACTORY.create(field.getName(), field, fieldType
, setter, getter, this.type, field.getDeclaringClass());
beanProperties.put(prop.getName(), prop);
if (LOGGER.isTraceEnabled() && parent != this.type) {
LOGGER.trace("类{}从父类{}中继承的属性:[{}]",
new Object[] { this.type.getName(),
parent.getName(), prop.getName() });
}
}
}
// 到父类中查找属性
initFromField(parent.getSuperclass());
}
// 初始化动态set get方法
private void initFromMethod(Class> type) {
Map> properties = new HashMap<>();
for (Method method : type.getMethods()) {
// 忽略Object对象
if (method.getDeclaringClass() == Object.class) {
continue;
}
if (ClassUtils.isGetter(method)) {
String propertyName = ClassUtils.getPropertyName(method);
if (!hasBeanProperty(propertyName)) {
Map prop = getProperty(properties,
propertyName);
prop.put("get", method);
prop.put("ownerType", type);
// 因为先使用field初始化了,所以现在都应该只剩动态getter或动态setter了
/*try {
Field field = ClassUtils
.getField(method.getDeclaringClass(), propertyName);
prop.put("field", field);
if (field.getType() == method.getReturnType()) {
prop.put("get", method);
} else {
prop.put("get", method);
}
} catch (NoSuchFieldException e) {
LOGGER.debug(e.getMessage());
}*/
}
}
if (ClassUtils.isSetter(method)) {
String propertyName = ClassUtils.getPropertyName(method);
if (!hasBeanProperty(propertyName)) {
Map prop = getProperty(properties,
propertyName);
prop.put("set", method);
prop.put("ownerType", type);
}
// 因为先使用field初始化了,所以现在都应该只剩动态getter或动态setter了
/*
if (prop.get("field") == null) {
try {
Field field = ClassUtils.getField(method.getDeclaringClass(),
propertyName);
prop.put("field", field);
} catch (NoSuchFieldException e) {
LOGGER.debug(e.getMessage());
}
}*/
}
}
for(Map prop : properties.values()) {
Class> propertyType = null;
Class> declaringType = null;
String propertyName = null;
// Field field = null;
Method setter = null;
Method getter = null;
/*if (prop.get("field") != null) {
field = (Field) prop.get("field");
declaringType = field.getDeclaringClass();
propertyName = field.getName();
propertyType = getGenericType(field.getGenericType(), field.getType());
} */
if (prop.get("get") != null) {
getter = (Method) prop.get("get");
declaringType = LangUtils.pick(declaringType, getter.getDeclaringClass()) ;
propertyType = LangUtils.pick(propertyType
, getGenericType(getter.getGenericReturnType(), getter.getReturnType()));
propertyName = LangUtils.pick(propertyName, ClassUtils.getPropertyName(getter));
}
if (prop.get("set") != null) {
setter = (Method) prop.get("set");
declaringType = LangUtils.pick(declaringType, setter.getDeclaringClass()) ;
propertyType = LangUtils.pick(propertyType
, getGenericType(setter.getGenericParameterTypes()[0], setter.getParameterTypes()[0]));
propertyName = LangUtils.pick(propertyName, ClassUtils.getPropertyName(setter));
}
BeanProperty> property = FACTORY.create(propertyName, null,
propertyType, setter, getter, type, declaringType);
beanProperties.put(property.getName(), property);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("类{}的属性:[{}], 定义子类{}",
new Object[] { property.getOwnerType().getName(),
property.getName(), property.getDeclaringType().getName()});
}
}
}
private Class> getGenericType(Type genericTypeDeclaring, Class> genericType) {
Type gt = typeGenericParams.get(genericTypeDeclaring.toString());
// 判断类型定义的泛型参数
if (gt == null) {
return genericType;
} else {
return (Class>) gt;
}
}
private Map getProperty(
Map> properties, String propertyName) {
Map prop = properties.get(propertyName);
if (prop == null) {
prop = new HashMap<>();
properties.put(propertyName, prop);
}
return prop;
}
/**
* @return 返回beanProperties
*/
@SuppressWarnings("unchecked")
public Collection> getBeanProperties() {
return beanProperties.values();
}
/**
*
* 返回指定索引属性.
*
*
* @param index
* 索引
* @return 指定属性
*/
public BeanProperty> getBeanProperty(int index) {
return (BeanProperty>) beanProperties.getValue(index);
}
/**
*
* 返回指定属性. 如果没有则抛出NoSuchPropertyException异常
*
*
* @param name
* 属性名
* @return 指定属性
*/
public BeanProperty> getBeanProperty(String name) {
BeanProperty> property = (BeanProperty>) beanProperties.get(name);
if (property == null) {
throw new NoSuchPropertyException(type, name);
}
return property;
}
/**
*
* 返回指定属性是否存在
*
*
* @param name
* 属性名
* @return 指定属性是否存在
*/
public boolean hasBeanProperty(String name) {
return beanProperties.get(name) != null;
}
/**
*
* 返回指定子孙属性. 如果没有则抛出NoSuchPropertyException异常
*
*
* @param name
* 属性名
* @return 指定属性
*/
public BeanProperty> getChildBeanProperty(String name) {
if (name.contains(DOT)) {
String currentPropertyName = name.substring(0, name.indexOf(DOT));
String innerPropertyName = name.substring(name.indexOf(DOT) + 1);
BeanProperty> property = getBeanProperty(currentPropertyName);
BeanDescriptor> propertyDescriptor = getBeanDescriptor(
property.getType());
return propertyDescriptor.getChildBeanProperty(innerPropertyName);
} else {
return getBeanProperty(name);
}
}
/**
*
* 查找并返回第一个符合条件BeanProperty. 如果没有则返回null.
*
*
* @param condition
* 条件判断
* @return 第一个符合条件BeanProperty
*/
public BeanProperty> findBeanProperty(BeanPropertyMatcher condition) {
for (BeanProperty> beanProperty : getBeanProperties()) {
if (condition.match(beanProperty)) {
return beanProperty;
}
}
return null;
}
/**
*
* 查找并返回所有符合条件BeanProperty的集合. 如果没有则返回一个长度为0的集合.
*
*
* @param condition
* 条件判断
* @return 所有符合条件BeanProperty的集合
*/
public Collection> findBeanPropertys(
BeanPropertyMatcher condition) {
Collection> coll = new ArrayList<>();
for (BeanProperty> beanProperty : getBeanProperties()) {
if (condition.match(beanProperty)) {
coll.add(beanProperty);
}
}
return coll;
}
/**
*
* 设置属性
*
*
* @param obj
* 目标对象
* @param name
* 属性名称
* @param value
* 属性值
*/
@SuppressWarnings("unchecked")
public void setProperty(T obj, String name, Object value) {
if (name.contains(DOT)) {
String currentPropertyName = name.substring(0, name.indexOf(DOT));
String innerPropertyName = name.substring(name.indexOf(DOT) + 1);
BeanProperty> property = getBeanProperty(currentPropertyName);
@SuppressWarnings("rawtypes")
BeanDescriptor propertyDescriptor = getBeanDescriptor(
property.getType());
Object propertyValue = property.getValue(obj);
// 中间层次为空,使用默认构造函数生成一个空对象
if (propertyValue == null) {
try {
if (ClassUtils.isCellection(property.getType())) {
LOGGER.trace(
"类{}的属性[{}]为空,对象为Collection接口实现类,自动创建该属性对象",
new Object[] {
property.getOwnerType().getName(),
property.getName() });
propertyValue = CollectionUtils
.newInstance(property.getType());
} else if (ClassUtils.isMap(property.getType())) {
LOGGER.trace("类{}的属性[{}]为空,对象为MAP接口,自动创建该属性对象",
new Object[] {
property.getOwnerType().getName(),
property.getName() });
propertyValue = CollectionUtils
.newMap(property.getType());
} /*
* else if (property.getType() == List.class) {
* LOGGER.trace(
* "类{}的属性[{}]为空,对象为List接口,自动创建该属性对象[使用ArrayList]" , new
* Object[] {property.getOwnerType().getName() ,
* property.getName()}); propertyValue = new
* ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy