《step3:tiny-Spring-IoC学习三》——为bean注入属性

本文介绍如何在Spring IoC中为bean注入属性,通过创建PropertyValue对象存储注入信息并保存到BeanDefinition。采用Field注入方式,利用Java反射的Field类来设置类的属性值。在AutowireCapableBeanFactory类中,结合Class的getDeclaredField()方法和Field的set()方法实现属性注入。
摘要由CSDN通过智能技术生成

        

        这一步,我们想要为bean注入属性。我们选择将属性注入信息保存成PropertyValue对象,并且保存到BeanDefinition中。这样在初始化bean的时候,我们就可以根据PropertyValue来进行bean属性的注入。Spring本身使用了setter来进行注入,这里为了代码简洁,我们使用Field的形式来注入。


-------------------------------------------------------------

   注意Field类位于java.lang.reflect包下。

Java反射中Field类描述的是:类的属性信息。简而言之,通过Field类的一些常用方法,可以设置类的属性值等。详细情况请参考java api

-------------------------------------------------------------

     类图:


    时序图:

 

      代码:

      1·BeanFactory接口:

package us.codecraft.tinyioc.factory;/**
 * Created by 贾丽敏 on 2017/5/29.
 */

import us.codecraft.tinyioc.BeanDefinition;

/**
 * @author
 * @create 2017-05-29 15:14
 **/
public interface BeanFactory {

    //获取bean
    Object getBean(String name);

    //注册bean
    void registerBeanDefinition(String name, BeanDefinition beanDefinition) throws Exception;

}

     2·AbstractBeanFactory抽象类:

package us.codecraft.tinyioc.factory;/**
 * Created by 贾丽敏 on 2017/5/29.
 */

import us.codecraft.tinyioc.BeanDefinition;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* 
* @author 
* @create 2017-05-29 15:17
**/
public abstract class AbstractBeanFactory implements BeanFactory {

    private Map<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();


    public Object getBean(String name) {
        return beanDefinitionMap.get(name).getBean();
    }

    public void registerBeanDefinition(String name, BeanDefinition beanDefinition) throws Exception {
        Object bean = doCreateBean(beanDefinition);
        beanDefinition.setBean(bean);
        beanDefinitionMap.put(name,beanDefinition);
    }

    //初始化bean
    protected abstract Object doCreateBean(BeanDefinition beanDefinition) throws Exception;
}
    
     3·子类AutowireCapableBeanFactory:

package us.codecraft.tinyioc.factory;/**
 * Created by 贾丽敏 on 2017/5/29.
 */

import us.codecraft.tinyioc.BeanDefinition;
import us.codecraft.tinyioc.PropertyValue;

import java.lang.reflect.Field;

/**
* 自动初始化bean
* @author 
* @create 2017-05-29 15:23
**/
public class AutowireCapableBeanFactory extends AbstractBeanFactory {

    @Override
    protected Object doCreateBean(BeanDefinition beanDefinition) throws Exception {
            Object bean = createBeanInstance(beanDefinition);
            applyPropertyValues(bean,beanDefinition);
            return bean;
    }

    protected Object createBeanInstance(BeanDefinition beanDefinition) throws Exception{
        return beanDefinition.getBeanClass().newInstance();
    }

    protected void applyPropertyValues(Object bean,BeanDefinition beanDefinition) throws Exception{
        for(PropertyValue propertyValue:beanDefinition.getPropertyValues().getPropertyValueList()){
            //Field类:描述类的属性信息,在这里,将对应的属性绑定(设置)到相应的object对象中
            Field declaredField=bean.getClass().getDeclaredField(propertyValue.getName());
            declaredField.setAccessible(true);
            declaredField.set(bean,propertyValue.getValue());
        }
    }


}

      4·bean对象封装类BeanDefinition:

package us.codecraft.tinyioc;/**
 * Created by 贾丽敏 on 2017/5/29.
 */

/**
* 
* @author 
* @create 2017-05-29 15:08
**/
public class BeanDefinition {

    private Object bean;
    private Class beanClass;
    private String beanClassName;
    private PropertyValues propertyValues;

    public PropertyValues getPropertyValues() {
        return propertyValues;
    }

    public void setPropertyValues(PropertyValues propertyValues) {
        this.propertyValues = propertyValues;
    }

    public Object getBean() {
        return bean;
    }

    public void setBean(Object bean) {
        this.bean = bean;
    }

    public Class getBeanClass() {
        return beanClass;
    }

    public void setBeanClass(Class beanClass) {
        this.beanClass = beanClass;
    }

    public String getBeanClassName() {
        return beanClassName;
    }

    public void setBeanClassName(String beanClassName) {

        this.beanClassName = beanClassName;
        try {
            //TODO:Class.forName?
            this.beanClass=Class.forName(beanClassName);
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }
}

     5·属性类PropertyValue:

package us.codecraft.tinyioc;/**
 * Created by 贾丽敏 on 2017/5/29.
 */

/**
* 
* @author 
* @create 2017-05-29 16:12
**/
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;
    }
}

     6·属性复合类PropertyValues:

package us.codecraft.tinyioc;/**
 * Created by 贾丽敏 on 2017/5/29.
 */

import com.sun.javafx.scene.control.skin.VirtualFlow;

import java.util.ArrayList;
import java.util.List;

/**
* 
* @author 
* @create 2017-05-29 16:14
**/
public class PropertyValues {

    private final List<PropertyValue> propertyValueList=new ArrayList<PropertyValue>();

    public void addPropertyValue(PropertyValue pv){
        this.propertyValueList.add(pv);
    }
    public List<PropertyValue> getPropertyValueList(){
        return  this.propertyValueList;
    }
}

    7·bean对象类HelloWorldService:

package us.codecraft.tinyioc;
/**
 * Created by 贾丽敏 on 2017/5/29.
 */

/**
* 
* @author 
* @create 2017-05-29 10:58
**/
public class HelloWorldService {
    private String text;

    public void setText(String text) {
        this.text = text;
    }

    public void printHelloWorld(){
        System.out.println("hello world   "+text);
    }
}

      8·测试类BeanFactoryTest:

package us.codecraft.tinyioc; /**
 * Created by 贾丽敏 on 2017/5/29.
 */

import org.junit.Test;
import us.codecraft.tinyioc.factory.AutowireCapableBeanFactory;
import us.codecraft.tinyioc.factory.BeanFactory;

/**
* 
* @author 
* @create 2017-05-29 10:59
**/
public class BeanFactoryTest {

    @Test
    public void test() throws  Exception{
        //1·初始化beanFactory
        BeanFactory beanFactory = new AutowireCapableBeanFactory();
        //2` bean定义
        BeanDefinition beanDefinition= new BeanDefinition();
        beanDefinition.setBeanClassName("us.codecraft.tinyioc.HelloWorldService");

        //3` 属性设置
        PropertyValues pvs =new PropertyValues();
        pvs.addPropertyValue(new PropertyValue("text","jimmy"));
        beanDefinition.setPropertyValues(pvs);

        //4 注册bean
        beanFactory.registerBeanDefinition("helloWorldService",beanDefinition);
        //3·获取bean
        HelloWorldService helloWorldService=(HelloWorldService)beanFactory.getBean("helloWorldService");
        helloWorldService.printHelloWorld();
    }
}

     最终执行效果:



     为bean注入属性到此基本结束,下面是针对于属性注入的代码简单分析:


    与step2中不同的地方就是在HelloWorldServicebean对象中加入属性,然后通过Field形式来注入。具体代码体现在:AutowireCapableBeanFactory类。在step2中,该类的工作就是根据动态加载的类完成了bean对象的实例化工作;在step3中,该类不仅仅是bean对象的实例化工作,同时也加入的bean对象的属性注入,通过方法Class类的getDeclaredField(Stringname)方法,该方法是获取该Class中属性为nameField类对象,然后通过Field.set(Object bean,Object Value)方法,为该属性赋值,这就完成了bean类中属性的注入过程。



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值