模拟实现Spring IoC功能
为了加深理解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功能的更多相关文章
- 手动模拟实现Spring IOC功能(基于javaConfig风格)
以下文中spring特指spring frameWork项目,不含其它:如spring cloud等. 作为刚开始研究spring源码的小白,对于spring两大核心功能之一的IOC,虽说大致了解了B ...
- 自定义模拟一个Spring IOC容器
一.模拟一个IOC容器: 介绍:现在,我们准备使用一个java project来模拟一个spring的IOC容器创建对象的方法,也就是不使用spring的jar自动帮助我们创建对象,而是通过自己手动书 ...
- 自己模拟实现spring IOC原理
1.1.IoC是什么 Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对 ...
- Spring IOC 剖析
模拟实现 Spring Ioc 控制反转功能 使用 => 原理 => 源码 => 模拟实现 使用:了解 原理:熟悉 源码 And 模拟实现: 精通 对照 Spring 功能点 Spr ...
- 使用 Spring 2.5 注释驱动的 IoC 功能(转)
基于注释(Annotation)的配置有越来越流行的趋势,Spring 2.5 顺应这种趋势,提供了完全基于注释配置 Bean.装配 Bean 的功能,您可以使用基于注释的 Spring IoC 替换 ...
- spring IOC 模拟实现
IOC即inverse of control 控制反转 以前对象之间的引用是通过new来调用实现,有了Spring IOC,我们可以把对象之间的引用交给他来管理,这样就把控制权交给了Spring,所以 ...
- (反射+内省机制的运用)简单模拟spring IoC容器的操作
简单模拟spring IoC容器的操作[管理对象的创建.管理对象的依赖关系,例如属性设置] 实体类Hello package com.shan.hello; public class Hello { ...
- spring ioc aop 原理
spring ioc aop 原理 spring ioc aop 的原理 spring的IoC容器是spring的核心,spring AOP是spring框架的重要组成部分. 在传统的程序设计中,当调 ...
- J2EE进阶(十四)超详细的Java后台开发面试题之Spring IOC与AOP
J2EE进阶(十四)超详细的Java后台开发面试题之Spring IOC与AOP 前言 搜狐畅游笔试题中有一道问答题涉及到回答谈谈对Spring IOC与AOP的理解.特将相关内容进行整理. ...
随机推荐
- CentOS6.5下安装远程桌面服务端软件VNC Server
VNC 使您能够远程訪问和控制您的计算机从还有一计算机或移动设备上,不管你在世界的不论什么地方. 常见的使用情形,包含给同事和朋友提供桌面支持.远程管理您的服务器. 将 VNC Server部署到您想 ...
- node 上传文件 http client to post file
node做http client 发送post数据是很容易的事情,但要上传文件就不是太容易了主要是因为上传文件的报文和普通post是不太一样的 要了解http post可以看下这个 https://i ...
- 深入分析JavaWeb Item39 -- 监听器(Listener)学习进阶
一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ...
- <LeetCode OJ> 100. Same Tree
100. Same Tree Total Accepted: 100129 Total Submissions: 236623 Difficulty: Easy Given two binary tr ...
- HTML5游戏实战之20行代码实现打地鼠
之前写过一篇打地鼠的博客70行的代码实现打地鼠游戏,细致思考过后,发现70行代码都有点多余了,应用tangide的控件特性,能够将代码量缩减到20行左右. 先show一下终于成果,点击试玩:打地鼠.或 ...
- Java悲观锁和乐观锁
悲观的并发策略——Synchronized互斥锁 互斥锁是最常见的同步手段,在并发过程中,当多条线程对同一个共享数据竞争时,它保证共享数据同一时刻只能被一条线程使用,其他线程只有等到锁释放后才能重新进 ...
- SparkSQL 与 Spark Core的关系
不多说,直接上干货! SparkSQL 与 Spark Core的关系 Spark SQL构建在Spark Core之上,专门用来处理结构化数据(不仅仅是SQL). Spark SQL在Spark C ...
- C语言“%”运算符
C语言中运算符“%”是取余运算符,而非取模运算符.(运算符“%”在C/C++, JAVA中,为取余运算,而在Python中为取模运算) 对于一个C语言取余表达式a % b,设其值为result,有如下 ...
- jQuery在多个div中,删除指定项
之前工作中有一个需求,就是在一堆图片列表中,点击具体的图片,并从界面移除:点击具体的图片,下载:这是一个思路 <style type="text/css" media=&qu ...
- SQL学习——基础语句(4)
前面感觉真的好乱,想哪,写哪.这里慢慢整理…… SQL Having 语句 还是前面的那两个表: grade表: student表: 我们需要查找这里的s_id下的gradeValue的和,这就要分组 ...