SpringIOC容器Bean对象的实例化的模拟实现

第一步:
创建一个Bean属性对象,它的作用是来接受配置文件中bean标签的id和class属性的值

/**
 * 用来存放配置文件中bean标签里面的id和class的属性值
 */
public class MyBean {
    private String id;
    private String clazz;

    public MyBean() {
    }

    public MyBean(String id, String clazz) {
        this.id = id;
        this.clazz = clazz;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }
}

第二步:
引入dom4j和xpath的依赖(jaxp)

<!-- dom4j -->
<dependency>
    <groupId>dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>1.6.1</version>
</dependency>
<!-- XPath -->
<dependency>
    <groupId>jaxen</groupId>
    <artifactId>jaxen</artifactId>
    <version>1.1.6</version>
</dependency>

第三步:
自己创建sources包,并且在包下创建spring.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<!--    设置javaBean对应的bean标签-->
    <bean id="userDao" class="com.zks.Dao.UserDao"></bean>
    <bean id="userService" class="com.zks.Service.UserService"></bean>
</beans>

第四步:
在spring包下建立工厂也就是myFactory接口

/**
 * Bean 工厂 接口 定义
 */
public interface MyFactory {
    //通过ID属性值获取对象
    public Object getBean(String id);
}

第五步:
在spring包下创建myFactory接口的实现类MyClassPathXmlApplicationContext。

/**
 * 模拟Spring的实现
 * 1.通过带参构造器得到配置文件
 * 2.通过dom4j解析配置文件,得到List集合(里面存放bean标签的id和class的属性值)
 * 3.通过反射得到对应得实例化对象,放置在Map中
 * 4.通过id属性获取对应得实例化对象
 */
public class MyClassPathXmlApplicationContext implements MyFactory{
    private List<MyBean> beanList=new ArrayList<>();//其中每一个MyBean对象对应这一个bean标签
    private Map<String,Object> beanMap=new HashMap<>();//map中存放创建好的实例化对象

    /**
     * 通过带参构造器得到配置文件
     * @param fileName
     */
    public MyClassPathXmlApplicationContext(String fileName) {
        //通过dom4解析对应的文件
        this.parseXml(fileName);
        //获取实例化对象
        this.instanceBean();
    }
    /**
     *通过dom4j解析配置文件,得到list集合
     * 1.获取解析器
     * 2.获取配置文件的URL
     * 3.通过解析器解析配置文件
     * 4.通过Xpath语法解析,获取beans标签下的所有bean标签
     * 5.通过指定的解析语法解析文档对象,返回元素集合
     * 6.判断元素集合是否为空
     * 7.如果集合元素不为空,便利集合
     * 8.获取bean标签元素的属性(id,和class属性值)
     * 9.获取MyBean对象,将id和class属性值设置到对象中,再将对象设置到MyBean的集合中
     * @param fileName
     */
    private void parseXml(String fileName) {
        //1.获取解析器
        SAXReader saxReader=new SAXReader();
        //2.获取URL
        URL url=this.getClass().getClassLoader().getResource(fileName);
        try{
            //3.通过解析器解析配置文件
            Document document=saxReader.read(url);
//            // 4.通过Xpath语法解析,获取beans标签下的所有bean标签
//            XPath xPath=document.createXPath("beans/bean");
//            //5通过指定的解析语法解析文档对象,返回元素集合
//            List<Element>elementList=xPath.selectNodes(document);
            List<Element> elementList=document.selectNodes("beans/bean");
            //6判断它是否为空
            if(elementList!=null&&elementList.size()>0){
                //7便利集合
                for (Element element : elementList) {
                    String id=element.attributeValue("id");//id属性值
                    String clazz=element.attributeValue("class");//class属性值
                    //获取MyBean对象,将id和class属性值设置到对象中,再将对象设置到MyBean的集合中
                    MyBean myBean=new MyBean();
                    myBean.setClazz(clazz);
                    myBean.setId(id);
                    beanList.add(myBean);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    /**
     * 通过反射得到实例化对象,放到map中
     * 1.判断集合是不是为空
     * 2.通过class.forname().newInstance得到实例化对象
     * 3.放到map中
     */
    private void instanceBean()  {
        if(beanList!=null&&beanList.size()>0){
            for (MyBean myBean : beanList) {
                String id=myBean.getId();
                String clazz=myBean.getClazz();
                try{
                    Object object= Class.forName(clazz).newInstance();
                    beanMap.put(id,object);
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        }
    }

    @Override
    public Object getBean(String id) {
        Object object=beanMap.get(id);
        return object;
    }
}

第六步:按照spring.xml中的路径创建UserService和UserDao

第七步:创建测试类测试

public class MyBeanTest {
    public static void main(String[] args) {
        MyFactory myFactory=new MyClassPathXmlApplicationContext("spring.xml");
        UserDao userDao= (UserDao) myFactory.getBean("userDao");
        userDao.test();

    }
}

这里文件利用dom4j和xpath读取文件还可以这样写

public class FileTest {
    public static void main(String[] args) throws DocumentException {
        InputStream inputStream=FileTest.class.getClassLoader().getResourceAsStream("spring.xml");
        //获取解析器
        SAXReader saxReader=new SAXReader();
        //获取文档
        Document document = saxReader.read(inputStream);;
        List<Node> nodeList=document.selectNodes("/beans/bean");
        for (Node node : nodeList) {
            Element element= (Element) node;
            System.out.println(element.attributeValue("id"));
            System.out.println(element.attributeValue("class"));
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值