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. 关于padding被计算在width中问题——box-sizing相关

    目录 盒子模型 与box-sizing有什么关系 我们为什么要开历史的"倒车" bootstrap怎么解决的 控件的box-sizing 注意甄别 前一阵子遇到一个小问题,在同样的 ...

  2. luoguP1006 传纸条

    题目描述 Description 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个 m" role="presentation& ...

  3. boost::asio::tcp

    同步TCP通信服务端 #include <boost/asio.hpp> #include <iostream> using namespace boost::asio; in ...

  4. Vue中Class与Style如何动态绑定

    Class 可以通过对象语法和数组语法进行动态绑定: 对象语法: <div v-bind:class="{ active: isActive, 'text-danger': hasEr ...

  5. 向net core 3.0进击——项目发布与部署

    目录 前言 发布 测试 小结 前言 在经历过好多折腾后,总算是把部署走通了一遍,之前只是简单创建个工程在linux下部署,后来一直将这件事搁置,直到最近刚好团队入手一个小服务器,很显然是linux的, ...

  6. 设计模式(七)Builder模式

    Builder模式,从这个名字我们可以看出来,这种设计模式就是用于组装具有复杂结构的实例的. 下面还是以一个实例程序来解释这种设计模式,先看实例程序的类图. 这里为了调试方便,只实现其中一个功能Tex ...

  7. LogBack.xml文件配置

    Logback-spring.xml配置文件  1.日志级别:日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL, ...

  8. Nginx、WSGI、 uWSGI、 uwsgi的区别

    当我们部署完一个应用程序,浏览网页时具体的过程是怎样的呢?首先我们得有一个 Web 服务器来处理 HTTP 协议的内容,Web 服务器获得客户端的请求,交给应用程序,应用程序处理完,返回给 Web 服 ...

  9. flask插件之flask_session会话机制

    flask-session是flask框架的session组件,由于原来flask内置session使用签名cookie保存,该组件则将支持session保存到多个地方,如: redis:保存数据的一 ...

  10. ArcGIS Engine空间分析之缓冲区分析的实现

    缓冲分析(BufferAnalysis)的结果是一个面状要素——即缓冲要素,点状要素.线状要素和面状要素,被缓冲分析功能处理过之后,它们的周围产生一个缓冲区域,该区域即新产生的面状要素. 在缓冲方向上 ...