递归填充属性
简介
目前的 Spring 已经可以处理有参数的构造方法了,不过还无法配置属性信息,因此本文要解决属性填充问题
实现
首先利用 PropertyValue 存储一个属性和属性值,PropertyValues 用于包装 PropertyValue ,存储一个 Bean 的所有属性和属性值,当判断一个 Bean 的属性是不是另一个 Bean 时,就要利用 BeanReference 来判断了,如果是,就要先填充作为属性的 Bean 了
PropertyValue
package com.meteor;
public class PropertyValue { private final String name; private final Object value;
public PropertyValue(String name, Object value) { this.name = name; this.value = value; }
public String getName() { return name; }
public Object getValue() { return value; } }
|
用于存储一个字段和字段值
PropertyValues
package com.meteor;
import java.util.ArrayList; import java.util.List;
public class PropertyValues { private final List<PropertyValue> propertyValueList = new ArrayList<>();
public void addPropertyValue(PropertyValue pv) { this.propertyValueList.add(pv); }
public PropertyValue[] getPropertyValues() { return this.propertyValueList.toArray(new PropertyValue[0]); }
public PropertyValue getPropertyValue(String propertyName) { for (PropertyValue pv : this.propertyValueList) { if (pv.getName().equals(propertyName)) { return pv; } } return null; } }
|
用于包装 PropertyValue,存储一个 Bean 的所有字段和字段值
BeanReference
package com.meteor.factory.config;
public class BeanReference { private final String beanName;
public BeanReference(String beanName) { this.beanName = beanName; }
public String getBeanName() { return beanName; } }
|
用于判读该属性的值是不是一个 Bean
AbstractAutowireCapableBeanFactory
package com.meteor.factory.support;
import cn.hutool.core.bean.BeanUtil; import com.meteor.BeansException; import com.meteor.PropertyValue; import com.meteor.PropertyValues; import com.meteor.factory.config.BeanDefinition; import com.meteor.factory.config.BeanReference;
import java.lang.reflect.Constructor;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory { @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { bean = createBeanInstance(beanDefinition, beanName, args); applyPropertyValues(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } addSingleton(beanName, bean); return bean; }
protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) { try { PropertyValues propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { String name = propertyValue.getName(); Object value = propertyValue.getValue(); if (value instanceof BeanReference) { BeanReference beanReference = (BeanReference) value; value = getBean(beanReference.getBeanName()); } BeanUtil.setFieldValue(bean, name, value); } } catch (Exception e) { throw new BeansException("Error setting property values: " + beanName); } } }
|
主要是利用 BeanUtil 工具进行属性填充
测试