public BeanPropertyHandler(PropertyDescriptor pd) {
super(pd.getPropertyType(), pd.getReadMethod() != null, pd.getWriteMethod() != null);
this.pd = pd;
public MethodProperty(PropertyDescriptor property) {
super(property.getName(), property.getPropertyType(),
MethodProperty.discoverGenericType(property));
this.property = property;
this.readable = property.getReadMethod() != null;
this.writable = property.getWriteMethod
() != null;
@Nullable private PropertyDescriptor findExistingPropertyDescriptor(String propertyName, Class<?> propertyType) { for (PropertyDescriptor pd : this.propertyDescriptors) { final Class<?> candidateType; final String candidateName = pd.getName(); if (pd instanceof IndexedPropertyDescriptor) { IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd; candidateType = ipd.getIndexedPropertyType(); if (candidateName.equals(propertyName) && (candidateType.equals(propertyType) || candidateType.equals(propertyType.getComponentType()))) { return pd; else { candidateType = pd.getPropertyType(); if (candidateName.equals(propertyName) && (candidateType.equals(propertyType) || propertyType.equals(candidateType.getComponentType()))) { return pd; return null;
/**
* Return an array of non-simple bean properties that are unsatisfied.
* These are probably unsatisfied references to other beans in the
* factory. Does not include simple properties like primitives or Strings.
* @param mbd the merged bean definition the bean was created with
* @param bw the BeanWrapper the bean was created with
* @return an array of bean property names
* @see org.springframework.beans.BeanUtils#isSimpleProperty
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
PropertyValues pvs = mbd.getPropertyValues();
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
result.add(pd.getName());
return StringUtils.toStringArray(result);
private static PropertyDescriptor[] getDescriptors(Class<?> clazz) {
PropertyDescriptor[] pds;
List<PropertyDescriptor> list;
PropertyDescriptor[] pds2 = descriptors.get(clazz);
if (null == pds2) {
try {
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
pds = beanInfo.getPropertyDescriptors();
list = new ArrayList<PropertyDescriptor>();
for (int i = 0; i < pds.length; i++) {
if (null != pds[i].getPropertyType()) {
list.add(pds[i]);
pds2 = new PropertyDescriptor[list.size()];
list.toArray(pds2);
} catch (IntrospectionException ie) {
ie.printStackTrace();
pds2 = new PropertyDescriptor[0];
descriptors.put(clazz, pds2);
return (pds2);
PropertyDescriptor[] pds =
this.beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if (Class.class == beanClass &&
("classLoader".equals(pd.getName()) || "protectionDomain".equals(pd.getName()))) {
logger.trace("Found bean property '" + pd.getName() + "'" +
(pd.getPropertyType() != null ? " of type [" + pd.getPropertyType().getName() + "]" : "") +
(pd.getPropertyEditorClass() != null ?
"; editor [" + pd.getPropertyEditorClass().getName() + "]" : ""));
public static <T> void findBooleanIsMethods(Class<T> clazz, PropertyDescriptor descriptor)
throws IntrospectionException {
if (descriptor.getReadMethod() == null && descriptor.getPropertyType() == Boolean.class) {
try {
PropertyDescriptor pd = new PropertyDescriptor(descriptor.getName(), clazz);
descriptor.setReadMethod(pd.getReadMethod());
} catch (IntrospectionException e) {
public void setEntityProperty( Entity entity, String property, Object value ) {
PropertyDescriptor descriptor = getDescriptorForEntityProperty( entity.getClass(), property );
if ( descriptor != null ) {
Class<?> cls = descriptor.getPropertyType();
if ( cls != null ) {
if ( ( value == null ) || ( cls.isAssignableFrom( value.getClass() ) ) ) {
try {
descriptor.getWriteMethod().invoke( entity, value );
return;
catch ( Exception e ) {
logger.error( "Unable to set entity property {}", property, e );
try {
descriptor.getWriteMethod().invoke( entity, mapper.convertValue( value, cls ) );
return;
catch ( Exception e ) {
logger.error( "Unable to set entity property {}", property, e );
entity.setDynamicProperty( property, value );
public BeanClassProperty(PropertyDescriptor descriptor) { type = descriptor.getPropertyType(); readMethodName = descriptor.getReadMethod().getName(); writeMethodName = descriptor.getWriteMethod().getName(); getter = createGetterFunction(); setter = createSetterFunction(paramGetter -> writeMethodName + "(" + paramGetter + ")"); name = descriptor.getName(); beanType = descriptor.getReadMethod().getDeclaringClass();
/**
* Perform a dependency check that all properties exposed have been set,
* if desired. Dependency checks can be objects (collaborating beans),
* simple (primitives and String), or all (both).
* @param beanName the name of the bean
* @param mbd the merged bean definition the bean was created with
* @param pds the relevant property descriptors for the target bean
* @param pvs the property values to be applied to the bean
* @see #isExcludedFromDependencyCheck(java.beans.PropertyDescriptor)
protected void checkDependencies(
String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, @Nullable PropertyValues pvs)
throws UnsatisfiedDependencyException {
int dependencyCheck = mbd.getDependencyCheck();
for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null && (pvs == null || !pvs.contains(pd.getName()))) {
boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType());
boolean unsatisfied = (dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_ALL) ||
(isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE) ||
(!isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
if (unsatisfied) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(),
"Set this property value or disable dependency checking for this bean.");
public BeanPropertyHandler(PropertyDescriptor pd) {
super(pd.getPropertyType(), pd.getReadMethod() != null, pd.getWriteMethod() != null);
this.pd = pd;
info = Introspector.
getBeanInfo(base.getClass());
} catch (Exception ex) {
info.getPropertyDescriptors().length);
for (PropertyDescriptor pd: info.getPropertyDescriptors()) {
pd.setValue("type", pd.getPropertyType());
pd.setValue("resolvableAtDesignTime", Boolean.TRUE);
list.add(pd);
public static void addProperties(BeanGenerator gen, PropertyDescriptor[] descriptors) { for (int i = 0; i < descriptors.length; i++) { gen.addProperty(descriptors[i].getName(), descriptors[i].getPropertyType());
PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if (Class.class == beanClass &&
("classLoader".equals(pd.getName()) || "protectionDomain".equals(pd.getName()))) {
logger.trace("Found bean property '" + pd.getName() + "'" +
(pd.getPropertyType() != null ? " of type [" + pd.getPropertyType().getName() + "]" : "") +
(pd.getPropertyEditorClass() != null ?
"; editor [" + pd.getPropertyEditorClass().getName() + "]" : ""));
if (d.getReadMethod() == null) {
continue;
if (d.getReadMethod().isAnnotationPresent(PersistentSequence.class)) {
Object val = d.getReadMethod().invoke(root);
if (!Collection.class.isAssignableFrom(val.getClass())) {
continue;
Collection<SettingsOwner> values = (Collection<SettingsOwner>) val;
BeanModelNodeSeq<SimpleBeanModelNode> seq = new BeanModelNodeSeq<>(d.getName());
} else if (d.getReadMethod().isAnnotationPresent(PersistentProperty.class)) {
node.addProperty(d.getName(), d.getReadMethod().invoke(root), d.getPropertyType());
propName, bean.getClass());
Class propertyType = descriptor.getPropertyType();
descriptor.getWriteMethod().invoke(bean, value);
/**
* 构造方法
* @param field 字段
* @param propertyDescriptor 字段name对应的property
public EntityField(Field field, PropertyDescriptor propertyDescriptor) {
if (field != null) {
this.field = field;
this.name = field.getName();
this.javaType = field.getType();
if (propertyDescriptor != null) {
this.name = propertyDescriptor.getName();
this.setter = propertyDescriptor.getWriteMethod();
this.getter = propertyDescriptor.getReadMethod();
this.javaType = propertyDescriptor.getPropertyType();
Method method = desc.getWriteMethod();
if (method == null) {
final String methodName = writeMethodNames.get(desc.getName());
if (methodName != null) {
method = MethodUtils.getAccessibleMethod(beanCls, methodName,
desc.getPropertyType());
if (method != null) {
try {
/**
* Compare the given {@code PropertyDescriptors} and return {@code true} if
* they are equivalent, i.e. their read method, write method, property type,
* property editor and flags are equivalent.
* @see java.beans.PropertyDescriptor#equals(Object)
public static boolean equals(PropertyDescriptor pd, PropertyDescriptor otherPd) {
return (ObjectUtils.nullSafeEquals(pd.getReadMethod(), otherPd.getReadMethod()) &&
ObjectUtils.nullSafeEquals(pd.getWriteMethod(), otherPd.getWriteMethod()) &&
ObjectUtils.nullSafeEquals(pd.getPropertyType(), otherPd.getPropertyType()) &&
ObjectUtils.nullSafeEquals(pd.getPropertyEditorClass(), otherPd.getPropertyEditorClass()) &&
pd.isBound() == otherPd.isBound() && pd.isConstrained() == otherPd.isConstrained());
info = Introspector.getBeanInfo(base.getClass());
} catch (Exception ex) {
info.getPropertyDescriptors().length);
for (PropertyDescriptor pd: info.getPropertyDescriptors()) {
pd.setValue("type", pd.getPropertyType());
pd.setValue("resolvableAtDesignTime", Boolean.TRUE);
list.add(pd);