递归填充属性

Meteor 2023-12-25 15:59:31
Categories: Tags:

简介

目前的 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;
}

/*
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) {
// A 依赖 B,获取 B 的实例化
BeanReference beanReference = (BeanReference) value;
value = getBean(beanReference.getBeanName());
}
// 属性填充,利用hutool工具包
BeanUtil.setFieldValue(bean, name, value);
}
} catch (Exception e) {
throw new BeansException("Error setting property values: " + beanName);
}
}
}

主要是利用 BeanUtil 工具进行属性填充

测试