为Bean注入Bean对象
Github链接:github.com/WangChao-ly…
建议订阅博主专栏,从下到上系统手写spring源码,体会其中过程!
- 学过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;
}
}
- 修改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);
}
}
- 测试
/**
* 为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");
}