TintySpring构建过程 Step3-属性注入

2019-01-19  本文已影响0人  ArthurPapa

在上一步中,我们实现了通过类名来创建一个没有参数的对并进行管理,现在我们进一步的,来添加一个能够注入属性值的工厂。我们暂时不支持在属性中注入其他Bean,现在做的只是对简单的属性进行注入,我们依然通过反射机制来完成这点。

  1. 我们需要对我们的BeanDefinition进行属性的注入,那么我们自然会想到使用一个对象来描述所有的属性值。我们定义一个对象PropertyValue来描述。(问题1:这里为什么不用一个MAP来解决问题,类似于Map<name,objecy>或者Map<name,PropertyValue>解答末尾)因为一个对象的属性不止一个,所以我们要建立一个List来存储这些PropertyValue,我们建立一个PropertyValues来存储PropertyValue

    PropertyValue

     public class PropertyValue {
         private String name;
         private Object value;
     
         public PropertyValue(String name, Object value) {
             this.name = name;
             this.value = value;
         }
     
         public String getName() {
             return name;
         }
     
         public void setName(String name) {
             this.name = name;
         }
     
         public Object getValue() {
             return value;
         }
     
         public void setValue(Object value) {
             this.value = value;
         }
     }
    

    PropertyValues

     public class PropertyValues {
         private  final List<PropertyValue> propertyValueList = new ArrayList<PropertyValue>();
     
         public PropertyValues() {
         }
     
         public boolean addPropertyValue(PropertyValue propertyValue){
             //判断是否会有重复的Value
             for (PropertyValue propertyValueTemp : propertyValueList){
                 if (propertyValueTemp.getName().equals(propertyValue.getName()))
                     return false;
             }
             propertyValueList.add(propertyValue);
             return true;
         }
     
         public List<PropertyValue> getPropertyValueList() {
             return propertyValueList;
         }
     }
    
  2. BeanDefinition中添加private PropertyValues propertyValues;以及相应的get set方法,并初始化PropertyValues(防止null)

  3. 重写AutowireCapableBeanFactory中的doCreateBean方法,使其支持属性注入的方式生成Bean。

     public class AutowireCapableBeanFactory extends AbstractBeanFactory {
     
         @Override
         public Object doCreateBean(BeanDefinition beanDefinition) throws InstantiationException, IllegalAccessException, NoSuchFieldException {
             Object bean = createBeanInstance(beanDefinition);
             //bean作为引用直接传入,会在方法里修改Bean的数值
             applyPropertys(bean,beanDefinition);
             return bean;
         }
     
         private Object createBeanInstance(BeanDefinition beanDefinition) throws IllegalAccessException, InstantiationException {
             return beanDefinition.getBeanClass().newInstance();
         }
     
         private void applyPropertys(Object bean,BeanDefinition beanDefinition) throws NoSuchFieldException, IllegalAccessException {
             //bean是严格实例化的对象 而BeanDefinition是一个Bean的形容性类
             for(PropertyValue propertyValue : beanDefinition.getPropertyValues().getPropertyValueList()){
                 Field delclaredFiled = bean.getClass().getDeclaredField(propertyValue.getName());
                 delclaredFiled.setAccessible(true);
                 delclaredFiled.set(bean,propertyValue.getValue());
             }
         }
    
  4. 测试

     @Test
     public void test() throws IllegalAccessException, NoSuchFieldException, InstantiationException {
         BeanFactory beanFactory = new AutowireCapableBeanFactory();
    
         //初始化BeanDefinition
         BeanDefinition beanDefinition = new BeanDefinition();
         beanDefinition.setClassName("com.arthur.HelloService");
         //设置相应的属性值
         PropertyValues propertyValues = new PropertyValues();
         propertyValues.addPropertyValue(new PropertyValue("name","big arthur"));
         propertyValues.addPropertyValue(new PropertyValue("favouriteFood","火鸡面"));
         propertyValues.addPropertyValue(new PropertyValue("age",new Integer(20)));
         beanDefinition.setPropertyValues(propertyValues);
    
         beanFactory.registerBeanDefinition("hello",beanDefinition);
         HelloService helloService = (HelloService) beanFactory.getBean("hello");
         helloService.hello();
         helloService.instroduce();
     }
    
  5. 总结:在Step-2的基础上添加了简单的属性注入功能,对所有设置的属性进行遍历然后根据其属性名设置属性。

问题1:为什么不用一个MAP来解决PropertyValuePropertyValues,类似于Map<name,objecy>或者Map<name,PropertyValue>解答末尾
问题1分析:在之后Spring的进一步扩展中,我们需要进一步的扩展PropertyValuePropertyValues这两个类的方法,使其适应后续的功能升级。在这里我们设计这两个类,就是要为我们后续能够添加新的功能做准备。

上一篇下一篇

猜你喜欢

热点阅读