美文网首页
TintySpring构建过程 Step3-属性注入

TintySpring构建过程 Step3-属性注入

作者: ArthurPapa | 来源:发表于2019-01-19 22:20 被阅读0次

    在上一步中,我们实现了通过类名来创建一个没有参数的对并进行管理,现在我们进一步的,来添加一个能够注入属性值的工厂。我们暂时不支持在属性中注入其他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这两个类的方法,使其适应后续的功能升级。在这里我们设计这两个类,就是要为我们后续能够添加新的功能做准备。

    相关文章

      网友评论

          本文标题:TintySpring构建过程 Step3-属性注入

          本文链接:https://www.haomeiwen.com/subject/amktjqtx.html