package org.dayatang.utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.beans.PropertyDescriptor; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * JavaBean工具类。 * * @author yyang (<a href="mailto:gdyangyu@gmail.com">gdyangyu@gmail.com</a>) */ public class BeanUtils { private static final Logger LOGGER = LoggerFactory.getLogger(BeanUtils.class); private final Object bean; private final BeanClassUtils beanClassUtils; public BeanUtils(final Object bean) { Assert.notNull(bean); this.bean = bean; beanClassUtils = new BeanClassUtils(bean.getClass()); } /** * 在两个Bean之间复制属性值 * * @param fromBean 作为复制源的Bean * @param toBean 作为复制目标的Bean */ private static void copyProperties(Object fromBean, Object toBean, String... excludeProps) { BeanUtils from = new BeanUtils(fromBean); BeanUtils to = new BeanUtils(toBean); Map<String, Object> values = from.getPropValues(); Set<String> propsToCopy = to.getWritablePropNames(); if (excludeProps != null) { propsToCopy.removeAll(Arrays.asList(excludeProps)); } for (String prop : propsToCopy) { if (values.containsKey(prop)) { Object value = values.get(prop); to.setPropValue(prop, value); } } } /** * 获得指定的JavaBean类型的所有属性的类型,包括从父类继承的属性 * * @return 一个Map,Key为属性名, Value为属性所属的类 */ public Map<String, Class<?>> getPropTypes() { return beanClassUtils.getPropTypes(); } /** * 获得指定的JavaBean类型的所有属性的类型,包括从父类继承的属性 * * @return 一个Map,Key为属性名, Value为属性所属的类 */ public Class<?> getPropType(String propName) { return getPropTypes().get(propName); } /** * 获得JavaBean的所有属性值,包括从父类继承的属性 * * @return 一个Map,其中Key为属性名,Value为属性值。 */ public Map<String, Object> getPropValues() { return getPropValues(getReadablePropNames()); } /** * 获得JavaBean的属性值的值,包括从父类继承的属性,不包含指定的属性。 * * @param excludePropNames 要排除的属性名 * @return 一个Map,其中Key为属性名,Value为属性值。 */ public Map<String, Object> getPropValuesExclude(String... excludePropNames) { return getPropValues(beanClassUtils.getReadablePropNamesExclude(excludePropNames)); } /** * 获得JavaBean的属性值的值,包括从父类继承的属性,不包含指定的属性。 * * @param excludeAnnotations 一批Annotation,被这些Annotation标注的属性将被排除 * @return 一个Map,其中Key为属性名,Value为属性值。 */ public Map<String, Object> getPropValuesExclude(Class<? extends Annotation>... excludeAnnotations) { return getPropValues(beanClassUtils.getReadablePropNamesExclude(excludeAnnotations)); } private Map<String, Object> getPropValues(Set<String> propNames) { Map<String, Object> results = new HashMap<String, Object>(); Map<String, PropertyDescriptor> props = beanClassUtils.getPropertyDescriptors(); try { for (String propName : propNames) { PropertyDescriptor propertyDescriptor = props.get(propName); Method readMethod = propertyDescriptor.getReadMethod(); if (readMethod == null) { continue; } Object value = readMethod.invoke(bean, new Object[]{}); results.put(propName, value); } } catch (Exception e) { throw new RuntimeException(e); } return results; } /** * 获得指定JavaBean类型的所有属性的名字,包括从父类继承的属性 * * @return JavaBean的属性名的集合 */ public Set<String> getPropNames() { return beanClassUtils.getPropNames(); } /** * 获得指定JavaBean类型的所有可读属性的名字,包括从父类继承的属性 * * @return JavaBean的属性名的集合 */ public Set<String> getReadablePropNames() { return beanClassUtils.getReadablePropNames(); } /** * 获得指定JavaBean类型的所有可读属性的名字,包括从父类继承的属性 * * @return JavaBean的属性名的集合 */ public Set<String> getWritablePropNames() { return beanClassUtils.getWritablePropNames(); } /** * 获得指定属性的值 * * @param propName 属性名 * @return 属性值 */ public Object getPropValue(String propName) { try { PropertyDescriptor propertyDescriptor = beanClassUtils.getPropertyDescriptors().get(propName); Method readMethod = propertyDescriptor.getReadMethod(); if (readMethod == null) { return null; } return readMethod.invoke(bean, new Object[]{}); } catch (Exception e) { throw new RuntimeException(e); } } /** * 设置属性值 * * @param key 要设置值的属性名 * @param value 要设置的值 */ public void setPropValue(String key, Object value) { for (Map.Entry<String, PropertyDescriptor> entry : beanClassUtils.getPropertyDescriptors().entrySet()) { if (!entry.getKey().equals(key)) { continue; } PropertyDescriptor propertyDescriptor = entry.getValue(); Method writeMethod = propertyDescriptor.getWriteMethod(); if (writeMethod == null) { continue; } try { writeMethod.invoke(bean, value); } catch (Exception ex) { } } } /** * 从properties填充属性值 * * @param properties 表示一批属性值的Map,Key为属性名,Value为属性值 */ public void populate(Map<String, ? extends Object> properties) { for (Map.Entry<String, ? extends Object> entry : properties.entrySet()) { setPropValue(entry.getKey(), entry.getValue()); } } /** * 从另一个Bean提取属性值,填充当前Bean的同名属性 * * @param otherBean 另外的JavaBean */ public void copyPropertiesFrom(Object otherBean) { copyProperties(otherBean, bean); } /** * 将当前Bean的属性值填充到另一个Bean的同名属性 * * @param otherBean 另外的JavaBean */ public void copyPropertiesTo(Object otherBean) { copyProperties(bean, otherBean); } /** * 从另一个Bean提取属性值,填充当前Bean的同名属性 * * @param otherBean 另外的JavaBean * @param excludeProps 不参与复制的属性名 */ public void copyPropertiesFrom(Object otherBean, String... excludeProps) { copyProperties(otherBean, bean, excludeProps); } /** * 将当前Bean的属性值填充到另一个Bean的同名属性 * * @param otherBean 另外的JavaBean * @param excludeProps 不参与复制的属性名 */ public void copyPropertiesTo(Object otherBean, String... excludeProps) { copyProperties(bean, otherBean, excludeProps); } public Map<String, PropertyInfo> getPropInfos() { Map<String, PropertyInfo> results = new HashMap<String, PropertyInfo>(); for (String propName : getPropNames()) { results.put(propName, new PropertyInfo(propName, getPropType(propName), getPropValue(propName))); } return results; } public PropertyInfo getPropInfo(String propName) { return getPropInfos().get(propName); } }