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. 搭建YUM本地仓库

    本文介绍如何利用CentOS 7 ISO光盘镜像搭建YUM本地仓库. 环境准备: (1)VMware15.5版本虚拟机 (2)CentOS-7-x86_64-DVD-1908光盘镜像文件 1. 搭建Y ...

  2. Java学习之面试题整理

    1,java 基本数据类型有几种?哪几种?(面试题) 8种 byte short int long float double char boolean 2,int类型是几个字节?(面试题) 4字节 3 ...

  3. PHP reset

    1.函数的作用:重置数组内部指针,并返回第一个元素 2.函数的参数: @param array  $array 3. 例子一: <?php $arr1 = []; $arr2 = [false, ...

  4. MySQL 插入记录时自动更新时间戳

    将字段设置成timestamp类型,同时默认值设置成 CURRENT_TIMESTAMP.

  5. java的数制转换(详解,全!)

    对于进制转换,c/c++要用到辗转相除,不仅浪费时间,还造成代码量繁多,而任意之间的进制转换还需要以十进制为跳板, 先将其他进制的数字转换为十进制,再将十进制转换为其他进制,而java中自带进制转换的 ...

  6. 整理了适合新手的20个Python练手小程序

    100个Python练手小程序,学习python的很好的资料,覆盖了python中的每一部分,可以边学习边练习,更容易掌握python. 本文附带基础视频教程:私信回复[基础]就可以获取的 [程序1] ...

  7. Android9.0 如何区分SDK接口和非 SDK接口

    刚刚有同学问我,不太了解 "非SDK接口" 是什么意思?android9.0有什么限制 ?apache的http也有限制 ? 而且现在的大部分系统都升级上来了,黑名单.灰名单和白名 ...

  8. Java基础(40)String、StringBuilder和StringBuffer的区别(TODO)

    一.String String实现了Serializable接口.Comparable<String>接口和CharSequence接口,并且使用final char value[]不可变 ...

  9. 项目spring boot 写es hbase 运行内存溢出

    本地项目运行正常.服务器上运行内存溢出. 项目内部同时做插入oracle,es,hbase 经过测试发现 同时插入es,hbase是服务器上就会出现内存溢出 如果只插入oracle+es 或oracl ...

  10. 一次flume exec source采集日志到kafka因为单条日志数据非常大同步失败的踩坑带来的思考

    本次遇到的问题描述,日志采集同步时,当单条日志(日志文件中一行日志)超过2M大小,数据无法采集同步到kafka,分析后,共踩到如下几个坑.1.flume采集时,通过shell+EXEC(tail -F ...