(造轮子)手写Spring框架-为Bean注入Bean对象

98 阅读1分钟

为Bean注入Bean对象

Github链接:github.com/WangChao-ly…

建议订阅博主专栏,从下到上系统手写spring源码,体会其中过程!

  1. 学过spring的都知道,为bean对象注入对象实例的时候,要求被注入的对象本身是一个bean对象,因此,我们在写为Bean注入Bean对象时候,只需要配置一个BeanReference,其中包含beanName就行,因为我们可以根据beanName在容器中找到bean对象实例,首先,我们编写BeanReference类:
public class BeanReference {
    private final String beanName;


    public BeanReference(String beanName) {
        this.beanName = beanName;
    }

    public String getBeanName(){
        return beanName;
    }
}
  1. 修改applyPropertyValues方法,原先只是简单的将name和value进行对应,现在需要添加一步,我们需要判断value是不是BeanReference,从而为bean注入bean对象:
protected void applyPropertyValues(String beanName,Object bean,BeanDefinition beanDefinition){
    try{
        for(PropertyValue propertyValue:beanDefinition.getPropertyValues().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 for bean: " + beanName, e);
    }
}
  1. 测试
/**
 * 为bean注入bean
 * @throws Exception
 */
@Test
public void testPopulateBeanWithBean() throws Exception {
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

    //注册Car实例
    PropertyValues propertyValuesForCar = new PropertyValues();
    propertyValuesForCar.addPropertyValue(new PropertyValue("brand","porsche"));
    BeanDefinition carBeanDefinition = new BeanDefinition(Car.class, propertyValuesForCar);
    beanFactory.registerBeanDefinition("car",carBeanDefinition);

    //注册Person实例
    PropertyValues propertyValuesForPerson = new PropertyValues();
    propertyValuesForPerson.addPropertyValue(new PropertyValue("name", "derek"));
    propertyValuesForPerson.addPropertyValue(new PropertyValue("age", 18));
    //Person实例依赖Car实例
    propertyValuesForPerson.addPropertyValue(new PropertyValue("car",new BeanReference("car")));
    BeanDefinition beanDefinition = new BeanDefinition(Person.class, propertyValuesForPerson);
    beanFactory.registerBeanDefinition("person",beanDefinition);

    Person person = (Person) beanFactory.getBean("person");
    System.out.println(person);

    Assert.equals(person.getName(),"derek");
    Assert.equals(person.getAge(),18);
    Car car = person.getCar();
    Assert.notNull(car);
    Assert.equals(car.getBrand(),"porsche");
}