手写一个简单的IOC

<!--解析xml-->
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

public class SimpleIOC {


    /*
    *
    *Map<id,Object>
     */
    private Map<String,Object> beans = new HashMap<>();
    public SimpleIOC(String path) throws Throwable{
            loadBeans(path);      
    }
    public <T>T getBean(String id){
        Object bean = beans.get(id);
        if(bean== null)
            throw new RuntimeException(id+":xml中没有注册该id");
        return (T)bean;
    }

    public <T>T getBean(Class beanClass){
       Collection<Object> values = beans.values();
       for (Object value : values) {
            if(value.getClass().equals(beanClass))return (T)value;
        }
        throw new NullPointerException(beanClass.getName()+":这个类型没有在xml中注册");
	}


    /**
     * 使用DOM4j来解析xml
     *
     *
     * @param path
     * @throws Throwable
     */
    private void loadBeans(String path)  throws Throwable{
        //加载xml
        SAXReader reader = new SAXReader();
        Document dom = reader.read(path);
        Element root = dom.getRootElement();
        List<Element> elements = root.elements();
        //String,Map<String,String> ->className,Map<fieldName,ref>
        Map<String,Map<String,String>> refs = new HashMap<>();

        for (Element element : elements) {
            String id = element.attributeValue("id");
            String className = element.attributeValue("class");    
            Map<String,String> propertyValue= new HashMap<>();
            List<Element> property = element.elements();
            Map<String,String> ref = new HashMap<>();
            for (Element pro : property) {//获取bean配置的属性值               
                if(existAttribute(pro,"value"))
                    propertyValue.put(pro.attributeValue("name"),pro.attributeValue("value"));
                else
                    ref.put(pro.attributeValue("name"),pro.attributeValue("ref"));
            }
            Class cl  = Class.forName(className);
            Object bean = cl.newInstance();//无参构造创建bean
            if(!ref.isEmpty())
                refs.put(className,ref);
            if(!propertyValue.isEmpty())//属性值不为空,将属性值装配到bean中
                assembleBean(cl,bean,propertyValue);
            beans.put(id,bean);
          
          }
        refreshBean(refs);
    }


    /**
     *遍历完xml,将所有bean加载到容器中,再给bean中属性值为ref的属性赋值;
     *String,Map<String,String> ->className,Map<fieldName,ref>
     * @param refs
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public void refreshBean(Map<String,Map<String,String>> refs) throws NoSuchFieldException, IllegalAccessException {
        if(refs.isEmpty())return;
        Iterator<String> iter = refs.keySet().iterator();
        while(iter.hasNext()){
            String className = iter.next();
            Object object = getBean(Class.forName(className));
            Map<String, String> refValue = refs.get(className);
            Iterator<String> fieldValue = refValue.keySet().iterator();
            while(fieldValue.hasNext()){
                String fieldName = fieldValue.next();
                String id = refValue.get(fieldName);
                Object refObject = getBean(id);
                Field field = object.getClass().getDeclaredField(fieldName);              
                field.setAccessible(true);
                field.set(object,refObject);
            }
        }
    }

    private boolean existAttribute(Element pro,String attributeName){
        return pro.attribute(attributeName) ==null ?false:true;
    }

    /*
    转换类型
     */
    private Object ConvertValueType(String type,String value) throws IllegalAccessException {
        switch (type){
            case "String":
                return value;
            case "Integer":
                return Integer.valueOf(value);
            case "int":
                return Integer.parseInt(value);
            case "Boolean":
                return Boolean.valueOf(value);
            case "boolean":
                return Boolean.parseBoolean(value);
            case "Short":
                return Short.valueOf(value);
            case "short":
                return Short.parseShort(value);
            case "Long":
                return Long.valueOf(value);
            case "long":
                return Long.parseLong(value);
            case "Byte":
                return Byte.valueOf(value);
            case "byte":
                return Byte.parseByte(value);
            case "Character":
                return Character.valueOf(value.charAt(0));
            case "char":
                return value.charAt(0);
            case "Double":
                return Double.valueOf(value);
            case "double":
                return Double.parseDouble(value);
            case "Float":
                return Float.valueOf(value);
            case "float":
                return Float.parseFloat(value);
            default:
                throw  new  RuntimeException("不支持");
        }
    }




    /**
     *
     * 8个基础属性 + 8个包装类+String:用value
     * 
     * 将配置的属性装配到bean中
     *
     * @param bean
     * @param propertyValue 配置的属性值
     * @return
     */
     private Object assembleBean(Class cl,Object bean,Map<String,String> propertyValue) throws IllegalAccessException {
         Field[] fields = cl.getDeclaredFields();
         for (Field field : fields) {
             field.setAccessible(true);
             String fieldName = field.getName();
             if(propertyValue.containsKey(fieldName)) {
                 Object valueObject = ConvertValueType(field.getType().getSimpleName(),propertyValue.get(fieldName));
                 field.set(bean,valueObject);
             }
         }
         return bean;
     }



}


xml配置


<beans>
    <bean id="conTest" class="com.myd.springioc.ConTest">
    <property  name="sex" value="man"/>
    <property  name="ID" value="QEWQWE"/>
    <property  name="age" value="123"/>
    <property  name="people" ref="pp"/>
    </bean>

    <bean id="pp" class="com.myd.springioc.People">
        <property name="name" value="people-number1"/>
        <property name="age" value="123"/>
        <property name="ID" value="qwer23234"/>
    </bean>

</beans>

测试类

public class Test {

    public static void main(String[] args)throws Throwable {
        SimpleIOC ioc = new SimpleIOC("src/main/resources/ioc.xml");
        ConTest conTest = ioc.getBean(ConTest.class);
        System.out.println(conTest.toString());
        System.out.println(conTest.people.toString());
        System.out.println("====================================");
        People people = ioc.getBean("pp");
        System.out.println(people);
    }

}


结果:
ConTest{name='null', sex='man', age=123, ID='QEWQWE'}
People{name='people-number1', age=123, ID='qwer23234'}
====================================
People{name='people-number1', age=123, ID='qwer23234'}


===============================================================
更新:最近重新写了ioc容器,可以在xml中定义一个ComponentScan标签用来扫描注解@Component,使用了@Component的class可以将该class注入到ioc容器中,另外还实现了@Autowried,实现类型自动注入;

Gitee地址:地址

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值