利用反射技术手写一个简单的IOC

本文探讨了IOC(控制反转)的概念,解释了如何将对象创建的控制权交给容器,如Spring。同时阐述了依赖注入的原理,即由容器负责对象实例的创建和属性赋值。文章还提到了Spring的IOC容器本质上是一个以类名为键的映射,以及在存在类名冲突时可能出现的问题。通过person.properties文件的示例,进行了实际的测试操作。
摘要由CSDN通过智能技术生成

IOC:控制反转和依赖注入

          控制反转:把创建对象的控制权交给容器,例如spring容器,创建对象是由容器创建,而不是自己new出来。

          依赖注入:当需要用到对象实例的时候,由容器把对象创建好,并且属性赋值好,然后注入进来。直接调用就可以了。

注:spring的IOC容器实际上是一个map,用类的名字作为键来存储类,因此如果有多个同样的类命名,会报出找到多个类的错误。

/**
 * 实体类
 */
public class Person {
    private String name;

    private Integer age;

    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}

 

/**
 * IOC工具类
 */
public class MyIoc {

    public Object getBean(String className) {
        Object object = null;
        try {
            //获取对应的类
            Class clazz = Class.forName(className);
            //获取构造函数
            Constructor constructor = clazz.getConstructor();
            //通过构造函数得到对象
            object = constructor.newInstance();

            //获取文件传入的属性
            Properties property = new Properties();

            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("person.properties");

            //String path = this.getClass().getClassLoader().getResource("person.properties").getPath();

            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);

            property.load(new InputStreamReader(bufferedInputStream, "UTF-8"));

            //property.load(new InputStreamReader(new FileInputStream(path),"UTF-8"));

            //获取对象的属性
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                //获取属性的类型
                Class fieldType = field.getType();

                String fieldName = field.getName();
                //手动拼接SET方法名
                StringBuilder stringBuilder = new StringBuilder("set");
                stringBuilder.append(fieldName.substring(0, 1).toUpperCase());
                stringBuilder.append(fieldName.substring(1));

                //找到对应的方法
                Method method = clazz.getMethod(String.valueOf(stringBuilder), fieldType);

                //获取属性类型对应的带String参数的构造方法
                Constructor fieldConstructor = fieldType.getConstructor(String.class);

                //通过从文件读出的对应属性的值,利用构造函数构获得传入对象的值
                Object value = fieldConstructor.newInstance(property.getProperty(fieldName));

                /*if (value instanceof String) {
                    value = new String(((String) value).getBytes("UTF-8"));
                }*/

                method.invoke(object, value);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return object;
    }
}

 

用于读取的文件:person.properties

 

测试一下:

public class IocTest {

    public static void main(String[] args) {
        MyIoc ioc = new MyIoc();

        Person person = (Person) ioc.getBean("com.xxx.ioc.Person");

        System.out.print(person);
    }
}

运行结果:

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值