简单的理解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(01).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. react 或 vue 中引用 jQuery 插件

    前言 今天与遇到一个令人抓狂的事情, 因为项目中有个交互太过于复杂而且冷门, 没有人封装类似react-swiper那种的移植过来的插件 只有现成的jQuery插件. 而时间并不宽裕,自己重写成rea ...

  2. 补充Mysql5.7用法

    下面简单介绍一下安装: [root@MySQL soft]# tar xf mysql-5.7.10-linux-glibc2.5-x86_64.tar.gz -C /data/service/ [r ...

  3. 解决Popup StayOpen=true时,永远置顶的问题

    Popup设置了StayOpen=true时,会置顶显示. 如弹出了Popup后,打开QQ窗口,Popup显示在QQ聊天界面之上. 怎么解决问题? 获取绑定UserControl所在的窗口,窗口层级变 ...

  4. 【python标准库模块三】Os模块和Sys模块学习

    Os模块 导入os模块 import os 获取当前工作目录 os.getcwd() 切换目录,跟linux中的cd一样 os.chdir("文件夹名") 递归生成文件夹 os.m ...

  5. 毕业回馈-89c51之定时器/计数器(Timer/Count)

    今天分享的是89c51系列单片机的内部资源定时器/计数器,在所有的嵌入式系统中都包含这两个内部功能. 首先先了解几个定时器/计数器相关的概念: •时钟周期:时钟周期 T 是时序中最小的时间单位,具体计 ...

  6. git使用之错误分析及解决(持续更新)

    错误一: 使用 $ git push -u origin master 出现如下错误: error: src refspec master does not match any. error: fai ...

  7. Linux 虚存的性能问题

    虚存子系统是所有 UNIX 系统的核心组件.下面讨论虚存系统的实现及其对操作系统中几乎其他所有子系统的作用和影响.首先详细说明一些基本的内存管理问题:然后具体分析 Linux 操作系统如何实施虚存管理 ...

  8. Swift基础之实现选择图片时,出现类似于ActionSheet的样式

    之前看到过有APP在选择图片时,调用手机相册时,将手机相册做成了左右滑动选择的效果,这次展示的就是这种样式,用OC语言已经有人实现过类似的代码,在这里写的仅仅是效果展示的代码调用,具体代码,可以自己研 ...

  9. ObjectOutputStream 和 ObjectInputStream的使用

    一.看一下API文档 ObjectOutputStream : ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream.可以使用 ObjectInp ...

  10. Android图表库MPAndroidChart(八)——饼状图的扩展:折线饼状图

    Android图表库MPAndroidChart(八)--饼状图的扩展:折线饼状图 我们接着上文,饼状图的扩展,增加折现的说明,来看下我们要实现的效果 因为之前对MPAndroidChart的熟悉,所 ...