实现Spring IOC

5 篇文章 0 订阅
1 篇文章 0 订阅

Spring作为经典的框架,作为java程序员多多少少对其源码会一定的了解,今天将对Spring IOC进行实现

1.实现需要以下
  1. junit单元测试,如有疑问请稳步java junit测试
  2. dom4j.jar对xml的解析,如有疑问请稳步使用dom4j.jar操作XML
  3. 反射与内省
  4. 类型的自动转换
2.需要解析的spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean name="a" class="zx.mes.hyl.bean.A">
        <property name="name" value="张三"></property>
        <property name="age" value="33"></property>
    </bean>

    <bean name="b" class="zx.mes.hyl.bean.B">
        <property name="name" value="李四"></property>
        <property name="a" ref="a"></property>
    </bean>
</beans>

3流程步骤

mySpring实现的步骤

4.config容器,从spring.xml中解析
public class ConfigManager {
    private static Map<String,Bean> config=new HashMap<String, Bean>();

    public static Map<String,Bean> getConfig(String path){
        //读取spring.xml
        SAXReader reader=new SAXReader();
        Document document=null;
        try {
            document=reader.read(ConfigManager.class.getResourceAsStream(path));
        } catch (DocumentException e) {
            e.printStackTrace();
            throw new RuntimeException("配置文件路径有问题,请检查");
        }
        //解析出bean
        String xpath="//bean";

        List<Element> eleBeans=document.selectNodes(xpath);
        if (eleBeans!=null) {
            for (Element eleBean : eleBeans) {
                Bean bean=new Bean();
                String name=eleBean.attributeValue("name");
                String className=eleBean.attributeValue("class");
                List<Element> properties= eleBean.elements("property");
                for (Element eleProp : properties) {
                    Property property=new Property();
                    property.setName(eleProp.attributeValue("name"));
                    property.setRef(eleProp.attributeValue("ref"));
                    property.setValue(eleProp.attributeValue("value"));
                    bean.getProperties().add(property);
                }
                bean.setName(name);
                bean.setClassName(className);

                config.put(name, bean);
            }
        }

        //添加到config中
        return config;
    }
}
5.context容器的实现

context容器步骤实现

6.相应的步骤的重要代码
public ClassPathXmlApplicationContext(String path){
        //初使化config
        Map<String, Bean> config=ConfigManager.getConfig(path);
        //初使化工厂 contex
        for (Entry<String, Bean> en : config.entrySet()) {
            String beanName=en.getKey();
            Bean b=en.getValue();
            //反射创建对象
            Object obj=null;
            try {
                if (!isExitBean(b.getName())) {
                    obj = createBean(b);
                    context.put(beanName, obj);
                }else{
                    obj=context.get(b.getName());
                }
                //分两种:
                if (b.getProperties()!=null) {
                    for (Property prop : b.getProperties()) {
                        String name=prop.getName();
                        String value=prop.getValue();
                        //1.值是value
                        if (value!=null && !"".equals(value)) {
                            //使用BeanUtils工具方法完成属性的注入//自动完成类型转换
                            Map<String, String[]> paramMap=new HashMap<String,String[]>();
                            paramMap.put(name, new String[]{value});
                            org.apache.commons.beanutils.BeanUtils.populate(obj, paramMap);
                            //Method mSetName=BeanUtils.getWriteMethod(name,clazz);
                            //mSetName.invoke(obj, value);
                        }
                        String ref=prop.getRef();
                        //2.值是ref类型
                        if (ref!=null) {
                            if (! isExitBean(ref)) {
                                Object obj2=Class.forName(config.get(ref).getClassName()).newInstance();
                                context.put(ref, obj2);
                            }
                            Method mSetRef=BeanUtils.getWriteMethod(name, obj.getClass());
                            mSetRef.invoke(obj, context.get(ref));
                        }
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("bean class="+b.getClassName()+"有问题,请检查"+",或者无空构造");
                throw new RuntimeException("bean class="+b.getClassName()+"有问题,请检查"+",或者无空构造");

            }
        }
    }
最后给上成功作业

成功作业
源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值