手写基于xml配置实现的ioc,实现控制反转!

目录

开发工具:

ioc介绍:

entity类:

Computer类:

 Memory类:

CPU类: 

xml文件:

XMLBeanFactory:

 


开发工具:

ideal maven java

ioc介绍:

IOC(Inverse of Controll)控制反转是一种程序设计思想。

控制是什么?

JavaBean(Java对象)的创建和管理

反转是什么?

一般情况下对象的创建和管理由开发者控制,反转是把对象的创建和管理交给容器完成,然后再交给开发者。

本篇博客将教会大家通过xml实现控制反转,彻底弄懂究竟是如何实现控制反转的。

entity类:

Computer类:

package com.dmdd.ioc;

public class Computer {
    private String brand;
    private Cpu cpu;
    private Memory memory;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Cpu getCpu() {
        return cpu;
    }

    public void setCpu(Cpu cpu) {
        this.cpu = cpu;
    }

    public Memory getMemory() {
        return memory;
    }

    public void setMemory(Memory memory) {
        this.memory = memory;
    }
    public void start (){
        System.out.println(brand+"品牌的电脑启动了");
        cpu.run();
        memory.read();
        memory.write();
    }
}

computer引用了两个类一个是 cpu 一个是 memory。

 Memory类:

package com.dmdd.ioc;

public class KingstonMemory implements Memory{
    @Override
    public void read() {
        System.out.println("金士顿内存读取数据");
    }

    @Override
    public void write() {
        System.out.println("金士顿内存写数据");
    }
}

package com.dmdd.ioc;

public class SumsungMemory implements Memory{
    @Override
    public void read() {
        System.out.println("三星内存条读取。。。。");
    }

    @Override
    public void write() {
        System.out.println("三星内存条写入。。。");
    }
}

CPU类: 

package com.dmdd.ioc;

public class AMDCpu implements Cpu{
    @Override
    public void run() {

    }
}
package com.dmdd.ioc;

public class IntelCpu implements Cpu{
    @Override
    public void run() {

    }
}

xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
<!--cpu对象-->
    <bean id="cpu" class="com.dmdd.ioc.IntelCpu"></bean>
<!--    memory对象-->
    <bean id="memory" class="com.dmdd.ioc.KingstonMemory"></bean>
<!--    computer对象-->
    <bean id="computer" class="com.dmdd.ioc.Computer">
        <!--    注入值类型的属性 name属性名 value注入值类型 ref注入引用类型-->
        <property name="brand" value="联想"></property>
        <property name="cpu" ref="cpu"></property>
        <property name="memory" ref="memory"></property>
    </bean>


</beans>

1.每一个bean代表一个对象 class属性代表的是哪个类。

2.property是bean对象里面的属性 name表示属性名 

3.value代表属性的值

4.ref代表引用的类型

XMLBeanFactory:

package com.dmdd.ioc.demo6;

import com.sun.xml.internal.fastinfoset.tools.StAX2SAXReader;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MyXMLBeanFactory {
    //配置文件名称
    private String fileName;
    //保存javabean的集合
    private Map<String, Object> beanMap = new HashMap<>();

    public MyXMLBeanFactory(String fileName) {
        this.fileName = fileName;
        parseXML();
    }

    /***
     * 解析XML
     */
    public void parseXML() {
        SAXReader reader = new SAXReader();
        //读取xml文件,获得文档对象
        try {
            Document doc = reader.read(MyXMLBeanFactory.class.getClassLoader().getResourceAsStream(fileName));
            //通过文档对象获得根节点
            Element root = doc.getRootElement();
            //通过根节点,查找所有的bean节点
            List<Element> beans = root.elements("beans");
            //这次循环将对象实例化添加到Map中去
            for (Element bean : beans) {
                //通过class属性,获得类型信息,实例化对象
                String aClass = bean.attribute("class").getValue();
                Class<?> aClass1 = Class.forName(aClass);
                Object beanObj = aClass1.newInstance();
                String id = bean.attribute("id").getValue();
                beanMap.put(id, beanObj);
            }
            //这次循环是将bean中的属性初始化
            for (Element bean : beans) {
                {
                    //读取bean节点中的property节点
                    List<Element> properties = bean.elements("property");
                    for (Element property : properties) {
                        Attribute value = property.attribute("value");
                        if (value != null) {
                            //如果是value就直接赋值
                            String name = property.attribute("name").getValue();
                            //通过id在map中获取bean对象
                            Object beanObj = beanMap.get(bean.attribute("id").getValue());
                            //通过名字找到属性,通过反射赋值
                            Field field = beanObj.getClass().getDeclaredField(name);
                            field.setAccessible(true);
                            field.set(beanObj, value.getValue());
                        }
                        //如果是ref,从Map中查找对象进行赋值
                        Attribute ref = property.attribute("ref");
                        if (ref!=null){
//通过ref找到需要注入到属性的对象
                            Object refObj = beanMap.get(ref.getValue());
                            //如果是value,直接赋值
                            String name = property.attribute("name").getValue();
                            //通过id在map中获得当前bean对象
                            Object beanObj = beanMap.get(bean.attribute("id").getValue());
                            //通过名字找到属性,通过反射赋值,将对象注入到属性中
                            Field field = beanObj.getClass().getDeclaredField(name);
                            field.setAccessible(true);
                            field.set(beanObj,refObj);

                        }
                    }

                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

    }
    /**
     * 获得JavaBean
     * @param beanName
     * @return
     */
    public Object getBean(String beanName){
        return beanMap.get(beanName);
    }
}

重要代码介绍:

 

//保存javabean的集合
private Map<String, Object> beanMap = new HashMap<>();//定义hashmap,键存id value存对象。
//通过类名.class创建反射对象,通过反射对象读取XML文件
Document doc = reader.read(MyXMLBeanFactory.class.getClassLoader().getResourceAsStream(fileName));
//通过class属性,获得类型信息
String aClass = bean.attribute("class").getValue();
Class<?> aClass1 = Class.forName(aClass);//Class.forName(类型信息)创建反射对象
Object beanObj = aClass1.newInstance();//创建类的对象
//读取bean节点中的property节点
List<Element> properties = bean.elements("property");
for (Element property : properties) //通过迭代器遍历循环
//通过id在map中获取bean对象
Object beanObj = beanMap.get(bean.attribute("id").getValue());
//通过对象.getclass创建反射对象,通过名字找到属性,通过反射赋值
Field field = beanObj.getClass().getDeclaredField(name);
//如果是ref,从Map中查找对象进行赋值
Attribute ref = property.attribute("ref");
//通过ref找到需要注入到属性的对象,在XML中ref的值为类对象id的值
 Object refObj = beanMap.get(ref.getValue());

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值