模拟实现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的理解.特将相关内容进行整理. ...
随机推荐
- [Golang] 从零開始写Socket Server(3): 对长、短连接的处理策略(模拟心跳)
通过前两章,我们成功是写出了一套凑合能用的Server和Client,并在二者之间实现了通过协议交流.这么一来,一个简易的socket通讯框架已经初具雏形了,那么我们接下来做的.就是想办法让这个框架更 ...
- Rails中关联数据表的添加操作(嵌套表单)
很早就听说有Web敏捷开发这回事,最近终于闲了下来,可以利用业余的时间学些新东西,入眼的第一个东东自然是Ruby on Rails.Rails中的核心要素也就是MVC.ORM这些了,因此关于Rails ...
- Linux 下安装 jdk-7u79-linux-x64.gz,jdk1.7.0_79,jdk1.7步骤:
1.首先下载对应CentOS版本的jdk:这里我下载的是jdk-7u79-linux-x64.tar.gz 2.上传到CentOS下的目录中 3.新建一个APP目录作为存储jdk的目录 4.解压jdk ...
- 英语发音规则---Q字母
英语发音规则---Q字母 一.总结 一句话总结: 1.Q/que发[k]音? Iraq [ɪ'rɑ:k] n. 伊拉克 cheque [tʃek] n. 支票 2.Qu-发[kw]? quality ...
- Statspack的使用
Statspack是Oracle 8i以上提供的一个非常好的性能监控与诊断工具,基本上全部包含了BSTAT/ESTAT的功能,更多的信息可以参考附带文档$ORACLE_HOME/rdbms/admin ...
- DBS-Oracle:表的连接查询
ylbtech-DBS-Oracle:表的连接查询 链接查询是指基于两个或两个以上表或试图的查询.在实际应用中,查询单个表可能无法满足应用程序的实际需求(例如显示雇员的部门名称以及雇员名),在这种情况 ...
- 微信小程序 | canvas绘图
1.新的尺寸单位 rpx rpx(responsive pixel): 可以根据屏幕宽度进行自适应. 规定屏幕宽为750rpx.如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则 ...
- Oracle自制事务
数据库事务是一种单元操作,要么全部操作成功,要么全部失败.在Oracle中,一个事务是从执行第一个数据操作语言(DML)语句开始的,直到执行一个COMMIT语句,提交保存事务,或执行一个ROLLBAC ...
- vue中slot的用法案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- HDU 1052 Tian Ji -- The Horse Racing【贪心在动态规划中的运用】
算法分析: 这个问题很显然可以转化成一个二分图最佳匹配的问题.把田忌的马放左边,把齐王的马放右边.田忌的马A和齐王的B之间,如果田忌的马胜,则连一条权为200的边:如果平局,则连一条权为0的边:如果输 ...