为了加深理解Spring 今天自己写了一个模拟的Spring....

步骤:

1.利用jdom解析bean.xml(pull,sax也能够,我这里用了jdom)

2.先解析全部的<bean/>,再解析全部的<property/>.假设边解析<bean/>,边解析<property/>,会导致property的ref找不到相应的bean.

3.利用反射,依据解析到的类路径,new出一个实例,实现Ioc.

文件夹结构:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

这里仅仅给出核心代码,其余的bean,dao,service,并不重要,就不给出了.有兴趣的同志能够点击~这里下载源代码.~

ClassPathXmlApplicationContext:

package glut.spring;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder; public class ClassPathXMLApplicationContext {
/**
* 用于存放<bean/>
*/
private Map<String, Object> beans = new HashMap<>();
/**
* 用于存放<property/>
*/
private Map<String, List<Element>> properties = new HashMap<>(); /**
* 将xml文件转为输入流,作为參数传入.
* @param is
* @throws Exception
*/
public ClassPathXMLApplicationContext(InputStream is) throws Exception {
// TODO Auto-generated constructor stub
autoWired(is);
} /**
* 模拟DI
* @param is
* @throws Exception
*/
private void autoWired(InputStream is) throws Exception {
SAXBuilder sb = new SAXBuilder(); Document doc = sb.build(is); Element rootElement = doc.getRootElement(); List<Element> elementOfBeans = rootElement.getChildren("bean"); //遍历xml中全部的<bean/>
for (Element e : elementOfBeans) { String beanId = e.getAttributeValue("id");
String beanClz = e.getAttributeValue("class"); Object beanInstance = Class.forName(beanClz).newInstance();
//将beanId和bean的实例存入map
beans.put(beanId, beanInstance);
//把全部的property先存着,等bean初始化完成再初始化property,否则可能会导致某些property无法初始化
properties.put(beanId, e.getChildren("property")); } //Dependency Injection Simulation
for (Entry<String, List<Element>> entry : properties.entrySet()) {
for (Element e : entry.getValue()) {
String propertyName = e.getAttributeValue("name");
String propertyRef = e.getAttributeValue("ref"); //通过set方法注入
String methodName = "set"
+ propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1); //通过beanId获得相应的bean
Object beanInstance = beans.get(entry.getKey()); //通过ref的值去寻找相应的bean,假设没有相应的bean,在以下用到getClass的时候会抛出异常.
Object refBeanInstance = beans.get(propertyRef); Method setterMethod = beanInstance.getClass().getMethod(
methodName,//呵呵,功能有点简陋,默认仅仅支持refBean实现的第一个接口.
refBeanInstance.getClass().getInterfaces()[0]); //调用相应的setter方法,将ref的bean注入到指定的bean中.
setterMethod.invoke(beanInstance, refBeanInstance); }
}
} /**
* 依据beanName获得bean
*/
public Object getBean(String beanName) {
// TODO Auto-generated method stub
return beans.get(beanName);
} }

測试代码:

package glut.test;

import glut.bean.User;
import glut.service.UserService;
import glut.spring.ClassPathXMLApplicationContext; import org.junit.Test; public class SpringTest {
@Test
public void test() throws Exception {
ClassPathXMLApplicationContext ctx = new ClassPathXMLApplicationContext(
this.getClass().getClassLoader()
.getResourceAsStream("beans.xml")); UserService userService = (UserService) ctx.getBean("userService"); User user = new User("user", "123"); userService.add(user);
}
}

打印的结果为User的toString:

User [uid=user, pwd=123]

模拟实现Spring IoC功能的更多相关文章

  1. 手动模拟实现Spring IOC功能(基于javaConfig风格)

    以下文中spring特指spring frameWork项目,不含其它:如spring cloud等. 作为刚开始研究spring源码的小白,对于spring两大核心功能之一的IOC,虽说大致了解了B ...

  2. 自定义模拟一个Spring IOC容器

    一.模拟一个IOC容器: 介绍:现在,我们准备使用一个java project来模拟一个spring的IOC容器创建对象的方法,也就是不使用spring的jar自动帮助我们创建对象,而是通过自己手动书 ...

  3. 自己模拟实现spring IOC原理

    1.1.IoC是什么 Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对 ...

  4. Spring IOC 剖析

    模拟实现 Spring Ioc 控制反转功能 使用 => 原理 => 源码 => 模拟实现 使用:了解 原理:熟悉 源码 And 模拟实现: 精通 对照 Spring 功能点 Spr ...

  5. 使用 Spring 2.5 注释驱动的 IoC 功能(转)

    基于注释(Annotation)的配置有越来越流行的趋势,Spring 2.5 顺应这种趋势,提供了完全基于注释配置 Bean.装配 Bean 的功能,您可以使用基于注释的 Spring IoC 替换 ...

  6. spring IOC 模拟实现

    IOC即inverse of control 控制反转 以前对象之间的引用是通过new来调用实现,有了Spring IOC,我们可以把对象之间的引用交给他来管理,这样就把控制权交给了Spring,所以 ...

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

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

  8. spring ioc aop 原理

    spring ioc aop 原理 spring ioc aop 的原理 spring的IoC容器是spring的核心,spring AOP是spring框架的重要组成部分. 在传统的程序设计中,当调 ...

  9. J2EE进阶(十四)超详细的Java后台开发面试题之Spring IOC与AOP

    J2EE进阶(十四)超详细的Java后台开发面试题之Spring IOC与AOP 前言   搜狐畅游笔试题中有一道问答题涉及到回答谈谈对Spring IOC与AOP的理解.特将相关内容进行整理.    ...

随机推荐

  1. hdoj--1051--Wooden Sticks(LIS)

    Wooden Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  2. ubuntu16.04+caffe训练mnist数据集

    1.   caffe-master文件夹权限修改 下载的caffe源码编译的caffe-master文件夹貌似没有写入权限,输入以下命令修改: sudo chmod -R 777 ~/caffe-ma ...

  3. c++面向对象程序设计 课后题 答案 谭浩强 第四章

    c++面向对象程序设计课后题答案 谭浩强 第四章 1: #include <iostream> using namespace std; class Complex {public: Co ...

  4. v-cli环境的安装

    第一步:node   npm是node的包管理器  yarn 第二步:npm install -g vue-cli或者淘宝镜像                  如果安装失败:在node.js com ...

  5. 为IT程序员量身定制的12个目标——很经典

    对程序员们来说挑战自我非常重要,要么不断创新,要么技术停滞不前.新年伊始,我整理了12个月的目标,每个目标都是对技术或个人能力的挑战,而且可以年复一年循环使用. 01. 变得有耐心 02. 保持健康 ...

  6. C# 读取硬盘信息 ManagementClass类

    一.在很多情况下,你可能都需要得到微机的硬件信息.需要加上下面的这句话: using System.Management; 获取硬件信息,需先知道硬件参数信息: Win32_Processor, // ...

  7. mac 调整Launchpad行列数目

    Mac调整Launchpad  行数和列数 开打Terminal终端依次输入以下三句: <1> 改变行数:defaults write com.apple.dock springboard ...

  8. 用私有构造器或枚举类型强化Singleton

    Singleton指只有一个实例的类,只能被创建一次. 在Java1.5之前实现Singleton有两种方式,都是将构造器设为private并导出公有的静态成员实例. 第一种方式将公有的静态成员实例设 ...

  9. 分清encodeURIComponent encodeURI 和 escape

    encodeURIComponent encodeURI escape 目的:这三个函数的作用都是让一段字符串在所有电脑(所有国家区域语言)上可读. escape对字符串进行处理: encodeURI ...

  10. 博客模板更新CSS

    采用了作者#a的模板BlueSky进行了些许修改 在原有基础上加了三个样式,使页面显示风格统一些 #home{ background-color:#fff; } #main{ background-c ...