为了加深理解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. USACO holstein 超时代码

    /* ID:kevin_s1 PROG:holstein LANG:C++ */第八组数据跪了.半天都不出结果 #include <iostream> #include <cstdi ...

  2. 具体验证身份证号码规则和姓名(汉字)的java代码

    一.验证汉字的正則表達式  /** 是否是汉字的正则 */  private String regexIsHanZi = "[\\u4e00-\\u9fa5]+";   * @pa ...

  3. struts2在action中获取request、session、application,并传递数据

    假设仅仅是通过request.session.application传递数据,则不须要获取对应的对象也能够传递数据,代码例如以下: ScopeAction.java: package com.ithe ...

  4. kentico中提示Message: An invalid SQL query was used.

    在调用CMSAbstractWebPart类的GetValue方法的时候出错. namespace CMS.PortalEngine.Web.UI{ /// <summary> /// B ...

  5. 杂项-Java:Spring Cloud

    ylbtech-杂项-Java:Spring Cloud Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册. ...

  6. 类扩展和category的小区别

    类扩展可以给类声明新的变量(属性),但是方法的实现只能在.m中实现 category可以给类声明新的方法实例,但是不可以添加变量(属性)

  7. iOS11访问相册权限变更问题

    手机升到iOS 11后  发现之前正常的图片保存功能无法正常使用  会闪退 经测试发现应该是权限没有开启的原因  但是NSPhotoLibraryUsageDescription已经写入plist   ...

  8. The Vertica Analytic Database:C-Store 7 Years Later笔记

    1.设计目标 Vertica数据库可以说是7年之后的C-Store,在2012年发表的这样一篇论文,描述了现在基于C-Store的一部分改进,当然,Vertica借鉴了很多C-Store的思想,但并非 ...

  9. call使用场景

    在javascript OOP中,定义: function cat(){    }    cat.prototype={    food:"fish",    say: funct ...

  10. SQL基本语句:2.基本表

    SQL基本表的增删改