简单的理解Spring的实现过程,模拟了Spring的读取配置文件

项目结构

主要代码如下

User.java
1
2
3
4
5
6
public class User {
    private String username;
    private String password;
 
    // getter and setter ..
}
beans.xml 配置文件
1
2
3
4
5
6
<beans>
    <bean id="u" class="com.demo.dao.impl.UserDAOImpl" />
    <bean id="userService" class="com.demo.service.UserService">
        <property name="userDAO" bean="u" />
    </bean>
</beans>
ClassPathXmlApplicationContext.java 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
 * 管理器
 * 
 * @author jerome_s@qq.com
 */
public class ClassPathXmlApplicationContext implements BeanFactory {
 
    private Map<String, Object> beans = new HashMap<String, Object>();
 
    /**
     * 初始化配置文件
     * 模拟spring配置文件。模拟大的工厂,把东西都写到大的配置文件,通过代码读取xml文件模拟spring。
     * 
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public ClassPathXmlApplicationContext() throws Exception {
        System.out.println("ClassPathXmlApplicationContext init.");
        SAXBuilder sb = new SAXBuilder();
 
        Document doc = sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); // 构造文档对象
        Element root = doc.getRootElement(); // 获取根元素HD
        List<Element> list = root.getChildren("bean");// 取名字为bean的所有元素
 
        // 循环每个bean
        for (int i = 0; i < list.size(); i++) {
            Element element = list.get(i);
            String id = element.getAttributeValue("id");
            String clazz = element.getAttributeValue("class");
            Object o = Class.forName(clazz).newInstance();
            System.out.println("ClassPathXmlApplicationContext bean's id = " + id);
            System.out.println("ClassPathXmlApplicationContext bean's class = " + clazz);
            beans.put(id, o);
 
            // 循环bean下的property
            for (Element propertyElement : (List<Element>) element.getChildren("property")) {
                // 调用 setUserDAO 设置 userDao的值
                String name = propertyElement.getAttributeValue("name"); // userDAO
                String bean = propertyElement.getAttributeValue("bean"); // u
                System.out.println("ClassPathXmlApplicationContext bean's property name = " + name);
                System.out.println("ClassPathXmlApplicationContext bean's property bean = " + bean);
 
                Object beanObject = beans.get(bean);// UserDAOImpl instance
 
                // userDAO -> setUserDao
                String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
 
                Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
                m.invoke(o, beanObject);
                System.out.println("ClassPathXmlApplicationContext bean's property invoke method " + methodName);
            }
 
            System.out.println("-------------------------");
        }
 
    }
 
    public Object getBean(String id) {
        return beans.get(id);
    }
 
}
UserService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class UserService {
    private UserDAO userDAO;
 
    public void add(User user) {
        userDAO.save(user);
    }
 
    public UserDAO getUserDAO() {
        return userDAO;
    }
 
    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }
}
UserDAOImpl.java
1
2
3
4
5
6
7
8
public class UserDAOImpl implements UserDAO {
 
    public void save(User user) {
        System.out.println("UserDAOImpl saved()");
        System.out.println("user.toString() = " + user.toString());
    }
 
}
运行结果如下
ClassPathXmlApplicationContext init.
ClassPathXmlApplicationContext bean's id = u
ClassPathXmlApplicationContext bean's class = com.demo.dao.impl.UserDAOImpl
-------------------------
ClassPathXmlApplicationContext bean's id = userService
ClassPathXmlApplicationContext bean's class = com.demo.service.UserService
ClassPathXmlApplicationContext bean's property name = userDAO
ClassPathXmlApplicationContext bean's property bean = u
ClassPathXmlApplicationContext bean's property invoke method name = setUserDAO
-------------------------
UserDAOImpl saved()
user.toString() = User [username=jerome, password=jeromepwd]


源码

简单模拟 Spring的更多相关文章

  1. (反射+内省机制的运用)简单模拟spring IoC容器的操作

    简单模拟spring IoC容器的操作[管理对象的创建.管理对象的依赖关系,例如属性设置] 实体类Hello package com.shan.hello; public class Hello { ...

  2. 一道面试题,简单模拟spring ioc

    自己实现的,程序写的土了点,很多情况没去考虑,主要是复习理解怎么使用反射来实现spring 的依赖注入. package dom4jtest; import java.lang.reflect.Inv ...

  3. 简单模拟Spring的注入

    主要就是读XML技术和反射技术. 在xml中读出相关配置信息,然后利用反射将其实例化为对象,并调用其构造方法,在实例化的过程中将属性注入实例. 实例化和属性注入这些操作都交给了框架,不再需要自己的去n ...

  4. 简单模拟Spring管理Bean对象

    1: 首先我们要利用dom4j进行xml的解析,将所有的bean的配置读取出来. 2:利用java的反射机制进行对象的实例化. 3: 直接获得对象 package cn.Junit.test; imp ...

  5. 【Spring系列】- 手写模拟Spring框架

    简单模拟Spring 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 前言 上次已经学习了 ...

  6. spring之mvc原理分析及简单模拟实现

    在之前的一篇博客中已经简单的实现了spring的IOC和DI功能,本文将在之前的基础上实现mvc功能. 一 什么是MVC MVC简单的说就是一种软件实现的设计模式,将整个系统进行分层,M(model ...

  7. java web学习总结(二十二) -------------------简单模拟SpringMVC

    在Spring MVC中,将一个普通的java类标注上Controller注解之后,再将类中的方法使用RequestMapping注解标注,那么这个普通的java类就够处理Web请求,示例代码如下: ...

  8. 工厂模式模拟Spring的bean加载过程

    一.前言    在日常的开发过程,经常使用或碰到的设计模式有代理.工厂.单例.反射模式等等.下面就对工厂模式模拟spring的bean加载过程进行解析,如果对工厂模式不熟悉的,具体可以先去学习一下工厂 ...

  9. 尚学堂Spring视频教程(一):模拟Spring

    Spring简单的说就是作为控制反转的容器,看这篇文章前需要先搞懂“控制反转和依赖注入“这个设计模式 我们先来模拟Spring,实现用户添加的功能,新建WEB项目”Spring_0100_Abstra ...

随机推荐

  1. TP中的AJAX返回ajaxReturn()

    系统支持任何的AJAX类库,Action类提供了ajaxReturn方法用于AJAX调用后返回数据给客户端.并且支持JSON.XML和EVAL三种方式给客户端接受数据,通过配置DEFAULT_AJAX ...

  2. 给定桩号获取纵断面中的高程值(c# for civil3d)

    通过civil3d提供的api,也就是纵断面Profile类提供的方法---public double ElevationAt(double station),就可以很轻松的获取纵断面对象某桩号处的高 ...

  3. 第一篇博客 ---- 分享关于Maven使用的一些技巧

    Maven环境搭建 在官网上下载maven安装包,地址:http://maven.apache.org/download.cgi . 解压文件到电脑坐在盘符目录,如E:\apache-maven-3. ...

  4. Bootstrap3 代码-程序输出

    通过 <samp> 标签来标记程序输出的内容. This text is meant to be treated as sample output from a computer prog ...

  5. 初始化openresty开发环境

    参考链接 https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04 初始化git ...

  6. 深入Java虚拟机(4)——网络移动性

    一.软件应用程序发展的几个阶段 软件应用程序发展经历了如下几个阶段: 服务于多个终端用户的大型计算机系统 孤立的个人计算机上运行孤立的软件 客户机/服务器模式 分布式处理模式 内容服务模式(网络移动性 ...

  7. Dynamics CRM2016 Set Values of all Data Types using Web API

    之前的博客里有谈到了web api的增删改查,里面会涉及到各种类型字段的赋值,因为时间和精力关系,没有对所有的字段类型一一测试,这篇博文中给出了全部的 http://inogic.com/blog/2 ...

  8. 网站开发进阶(四十四)input type="submit" 和"button"的区别

    网站开发进阶(四十四)input type="submit" 和"button"的区别   在一个页面上画一个按钮,有四种办法: 这就是一个按钮.如果你不写ja ...

  9. ECharts, PHP, MySQL, Ajax, JQuery 实现前后端数据可视化

    ECharts 下载js代码 工作原理浅析 在项目中引入ECharts 后台处理 数据库端MySQL PHP端 JQuery Ajax处理 ECharts 端处理 前端全部代码 演示结果 总结 最近要 ...

  10. 详解EBS接口开发之应收INVOICE导入

    (一)应收INVOICE常用标准表简介 1.1   常用标准表 如下表中列出了与应收INVOICE导入相关的表和说明: 表名 说明 其他信息 RA_BATCH_SOURCES_ALL AR事务处理来源 ...