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. 【JZOJ4807】破解

    Description 历经千辛万苦,ddddddpppppp 终于找到了IBN5100. dp 事先了解到SERN 共有T 个密码,每个密码是一个长度为N 的01 串,他要利用IBN5100 的特殊 ...

  2. bs4 UnicodeEncodeError: 'gbk' codec can't encode character '\xa0'

    Problem: 写爬虫时,出现了以下错误: 意思是Unicode编码错误,gbk编解码器不能编码\xa0字符. 爬取信息包含中文,使用BeautifulSoup库解析网页,用get_text()方法 ...

  3. navicat for mysql ;连接数据库报错1251,解决办法。

    转载 改密码方式:用管理员身份打开cmd mysql -uroot -p(输入密码)            进入mysql执行下面三个命令 use mysql: ALTER USER 'root'@' ...

  4. django html母版

    08.12自我总结 django母版 一.母版写的格式 在需要导入的地方写 {% block 名字定义 %} {% endblock %} 二.导入模板 {% extends 'FUCK.html' ...

  5. samba文件共享服务部署

    1.安装samaba服务程序 yum install -y samba 2.查看smaba文件,由于注释空行较多,选择过滤 egrep -v "#|;|^$" /etc/samba ...

  6. 什么是IDS/IPS?

    目录   摘要 0x00 基于网络的IDS和IPS0x01 设计考虑因素0X02 IDS/IPS 总结           摘要 摘要 这篇文章主要介绍的是入侵检测系统(IDS)和入侵防御系统(IPS ...

  7. PHP 调试脚本

    如果想要通过php.exe直接运行和调试脚本,可以在PHPStorm配置如下: 1.PHP安装XDebug的扩展. 2.在PHPStorm中,配置XDebug: 1) 打开菜单 "文件&qu ...

  8. ‎Cocos2d-x 学习笔记(12) Speed Follow

    Speed Follow都是直接继承了Action. Speed对其他action进行包装,改变action的速度. Follow可用于node在scene中的运动,scene将node作为Follo ...

  9. 不安分的管家——Jenkins

    占个位,持续补充. 一.使用Jenkins进行自动化部署 一直以来关于xx框架/中间件的技术博客有个奇怪的事情.这类文章特点大而全,重复率高,读者阅读完毕基本从安装到放弃. 作为一个使用者,我只是为了 ...

  10. 微信企业号开发入门(回调模式)java

    最近在开发微信企业号,刚接触时云里雾里的,在摸索过程中终于清晰了一点. 刚开始我以为订阅号.服务号.企业号的接口差不多,就一直用订阅号的教程来入门,后来才发现差的挺多的. 首先,微信企业号不像订阅号和 ...