Spring的IoC核心就是控制反转,将对实现对象的操作控制器交出来,由IoC容器来管理,从配置文件中获取配置信息,Java对XML文档提供了完美的支持,dom4j功能强大,而下面我就用JDOM这一开源项目,利用它可以纯Java技术实现对XML文档的解析、生成、序列化来模拟实现IoC容器。

一、传统方式完成项目。
        1.定义接口

package com.decipher.car;

public interface Car {
public String getBrand();
public void run(); }

2.接下来实现Car接口

package com.decipher.carImplementation;
import com.decipher.car.Car;
public class BMWCar implements Car{
private String MyBrand="宝马";
public String getBrand(){
return MyBrand;
}
public void run(){
System.out.println(MyBrand+" is runing");
}
}

3.新建一个Human类

package com.decipher.human;
import com.decipher.car.Car;
public class Human {
private Car car; public Car getCar() {
return car;
} public void setCar(Car car) {
this.car = car;
}
public void myCarRun(){
car.run();
}
}

4.最后编写测试类

package com.decipher.humen;

import com.decipher.car.Car;
import com.decipher.carImplementation.BMWCar;
import com.decipher.human.Human; public class HumenTest {
public static void main(String[] args) throws Exception {
Human human=new Human();
Car car=new BMWCar();
human.setCar(car);
human.myCarRun();
}
}

5.运行结果如图:

二.JDOM模拟IoC容器反转控制
在编程之前要导入jdom.jar包到项目工程目录中。
1.新建BeanFactory

package com.decipher.spring;

public interface BeanFactory {
public Object getBean(String id);
}

2.实现BeanFactory接口

package com.decipher.spring;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder; public class ClassPathXmlApplicationContext {
//储存各个实例的键值对
private Map<String,Object> beans=new HashMap<String,Object>();
//构造方法
public ClassPathXmlApplicationContext() throws Exception{
//读取XML文档
SAXBuilder sb=new SAXBuilder();
//构造文档对象DOC
Document doc=sb.build(this.getClass().getClassLoader().getResource("beans.xml"));
//获取XML文档根元素
Element root=doc.getRootElement();
//获取根元素下所有的子元素
List list=root.getChildren("bean");
//遍历所有的Bean元素
for(int i=0;i<list.size();i++){
//取得第i个Bean元素
Element element=(Element)list.get(i);
//获取第i个Bean元素的id属性值,并将其存入到字符串变量id中
String id=element.getAttributeValue("id");
//获取第i个Bean元素的class属性值,并将其存入到字符串变量clazz中
String clazz=element.getAttributeValue("class");
//使用反射生成类的对象,相当于生成类对象,且存储在Map中
Object o=Class.forName(clazz).newInstance();
System.out.println(id);
System.out.println(clazz);
beans.put(id,o);//将id和对象o存入Map中
//对第i个bean元素下的每个property子元素进行遍历
for(Element propertyElement:(List<Element>)element.getChildren("property")){
//获取property元素的name属性值
String name=propertyElement.getAttributeValue("name");
//获取property元素的bean属性值
String beanInstance=propertyElement.getAttributeValue("bean");
//取得被注入对象的实例
Object beanObject=beans.get(beanInstance);
//获取setter方法的方法名,形式为setXxx
String methodName="set"+name.substring(0, 1).toUpperCase()+name.substring(1);
System.out.println("method name= "+methodName);
//使用反射取得指定名称,指定参数类型的setXxx方法
Method m=o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
//调用对象o的setXxx方法
m.invoke(o,beanObject);
}
}
}
public Object getBean(String id){
return beans.get(id);
}
}

3.配置beans.xml文件

<beans>
<bean id="baomacar" class="com.decipher.carImplementation.BMWCar">
</bean>
<bean id="human" class="com.decipher.human.Human">
<property name="car" bean="baomacar"></property>
</bean>
</beans>

4.编写测试类HumenTest

package com.decipher.humen;

import com.decipher.spring.ClassPathXmlApplicationContext;
import com.decipher.car.Car;
import com.decipher.carImplementation.BMWCar;
import com.decipher.human.Human; public class HumenTest {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext();
Human human=(Human)ctx.getBean("human");
human.myCarRun();
}
}

5.运行如图:

6.总结
    从上面的两种实例化对象可以看出,传统的方式中,由程序员管理类对象,而在模拟的IoC容器中,将对类对象操作的控制器移交给IoC容器,由Ioc容器中的ApplicationContext处理XML配置文件,XML文件中每配置一个bean,即存储在Map中,不需要程序员再new一个对象,而直接从容器中获取即可,控制反转可以松耦,交出控制权利。

模拟实现IoC容器的更多相关文章

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

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

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

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

  3. IOC容器模拟实现

    运用反射机制和自定义注解模拟实现IOC容器,使其具有自动加载.自动装配和根据全限定类名获取Bean的功能. 一. 实现原理 1-1 IOC容器的本质 IOC容器可理解为是一个map,其中的一个entr ...

  4. Spring源码学习之:模拟实现BeanFactory,从而说明IOC容器的大致原理

    spring的IOC容器能够帮我们自动new对象,对象交给spring管之后我们不用自己手动去new对象了.那么它的原理是什么呢?是怎么实现的呢?下面我来简单的模拟一下spring的机制,相信看完之后 ...

  5. 通过中看不中用的代码分析Ioc容器,依赖注入....

    /** * 通过生产拥有超能力的超人实例 来理解IOC容器 */ //超能力模组接口 interface SuperModuleInterface{ public function activate( ...

  6. .net自带的IOC容器MEF使用

    IOC能做什么 IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合.更优良的程序. 控制反转: 将控制权移交给第三方容器  new 操作 依赖注入: 在程序 ...

  7. Ioc容器Autofac系列(1)-- 初窥

     一.前言 第一次接触Autofac是因为CMS系统--Orchard,后来在一个开源爬虫系统--NCrawler中也碰到过,随着深入了解,我越发觉得Ioc容器是Web开发中必不可少的利器.那么,Io ...

  8. IoC 之 2.2 IoC 容器基本原理(贰)

    2.2.1  IoC容器的概念 IoC容器就是具有依赖注入功能的容器,IoC容器负责实例化.定位.配置应用程序中的对象及建立这些对象间的依赖.应用程序无需直接在代码中new相关的对象,应用程序由IoC ...

  9. spring框架--IOC容器,依赖注入

    思考: 1. 对象创建创建能否写死? 2. 对象创建细节 对象数量 action  多个   [维护成员变量] service 一个   [不需要维护公共变量] dao     一个   [不需要维护 ...

随机推荐

  1. POJ1017&&UVA311 Packets(中文题面版)

    感谢有道翻译--- Description A工厂生产的产品是用相同高度h的方形包装,尺寸为1* 1,2 * 2,3 * 3,4 * 4,5 * 5,6 6.这些产品总是以与产品高度h相同,尺寸为66 ...

  2. Jmeter结构体系及运行顺序

    一:jmeter运行原理: jmeter时以线程的方式来运行的(由于jmeter是java开发的所以是运行在JVM虚拟机上的,java也是支持多线程的) 二:jmeter结构体系 1.取样器smapl ...

  3. SpringBoot 2.0整合阿里云OSS,实现动静分离架构

    前言 相信大部分开发者对下面这张架构图并不陌生吧,现在很多网站/应用都采用了动静分离的架构进行部署.博主的博客也不例外,主机采用的是阿里云的 ECS,使用 CDN 做静态内容分发,不过静态文件还是存储 ...

  4. opencv::模板匹配(Template Match)

    模板匹配介绍 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域. 所以模板匹配首先需要一个模板图像T(给定的子图像) 另外需要一个待检测的图像-源图像S 工作方法,在带检测图像上,从左到右,从 ...

  5. 日天老师的django相关博客

    Yuan先生的博客网址 1 Web应用 https://www.cnblogs.com/yuanchenqi/articles/8869302.html 2 http协议 https://www.cn ...

  6. KAFKA集群搭建(自带zookeeper)

    1. KAFKA下载地址:http://kafka.apache.org/downloads KAFKA-快速上手-官方网站:http://kafka.apache.org/quickstart 2. ...

  7. 判断浏览器是否支持指定CSS属性和指定值

    /** * @param attrName 属性名 * @param attrVal 属性值 * @returns {boolean} */ function isCssAttrSupported(a ...

  8. Day 3,学习的知识点

    年龄 如何判断是否未成年人 age = input('请输入你的年龄:')#input=输入age = int(age)#int=转化为整型if age < 18:    print('小妹妹你 ...

  9. 【C#多线程】2.线程池简述+两种传统的异步模式

    线程池简述+两种传统的异步编程模式 1.线程池简述 首先我们要明确一点,编程中讲的线程与平时我们形容CPU几核几线程中的线程是不一样的,CPU线程是指逻辑处理器,比如4核8线程,讲的是这个cpu有8个 ...

  10. 使用XPath

    XPath----XML路径语言 XPath概览 XPath是一门在XML文档中查找信息的语言,它提供了非常简洁明了的路径选择表达式. XPath常用规则 表达式 描  述 nodename 选取此节 ...