控制反转(IoC)-解析与实现
控制反转(Inversion of Control)缩写:IoC是面向对象编程中框架级别里的一个重要的概念,
可以说Spring框架的核心就是基于IoC原理的。
这个概念到底是什么呢?
这么讲吧,一个系统的运作肯定不是简单的几个类就可以实现的,它往往需要多个类的合作来实现业务逻辑
。这就使得每个对象都需要与其合作的对象具有相互的关系(依赖关系)。在早前编程中所需要的依赖对象
是通过自身去创建得到的,而现在是通过一个容器来统一管理这些依赖关系。在这整个过程中,对象获得其他对象引用的方式其实就是IoC。
IoC的本质是什么?
控制权的转移。IoC原理是基于面向对象中的设计原则的The Hollywood Principle:Don't call us,we'll call you(别找我,我会来找你的)。
可以这样讲,所有组件的初始化和调用都是由容器负责。在传统实现中类之间的关系是由类自己控制的(需要使用其他类时就自己创建),
但是在IoC中,组件处在容器中,由容器统一管理和调度。这就是"控制反转"的概念所在:控制权由应用代码转移到了容器中,即控制权的转移。
那如何实现IoC这种思想的呢?
实现IoC思想的方式主要有两种:依赖注入和依赖查找。
下面就以依赖注入为例讲解一下:
1.先定义一个部门接口:
public interface IDepartService {
//通过员工编号获得部门名字
public String getDepartNameByUser(int userId);
}
2.实现该接口:
public class DepartServiceImpl implements IDepartService {
@Override
public String getDepartNameByUser(int userId) {
if(userId==1){
return "IT部门";
}
return "";
}
}
3.定义一个用户类,该类中要维持部门对象的引用:
public class UserServiceImpl {
private IDepartService departService;
public void printInfo(int userId){
System.out.print(getUserName(userId));
System.out.println(departService.getDepartNameByUser(userId));
}
public String getUserName(int userId){
if(userId==1){
return "张三 ";
}
return "";
}
}
在用户类中,我们没有看到关于创建DepartService对象的语句。这里面我们没有采用常见的set注入或者构造方法注入,
而是采用反射的方法直接注入并执行的,要实现这个效果的话,我们需要定义一个容器,来管理他们的关系。
4.定义容器,我们在容器中先获取配置文件:
public class Container {
......
private void loadConfig() {
// TODO Auto-generated method stub
InputStream is = Container.class.getResourceAsStream("/ioc.properties");
properties = new Properties();
try {
properties.load(is);
} catch (Exception e) {
// TODO: handle exception
}
} public Object get(String name) {
String className = (String) properties.get(name);
return Class.forName(className).newInstance();
......
} public void inject(Object obj) {
Field[] fields = obj.getClass().getDeclaredFields();
......
for (Field field : fields) {
field.setAccessible(true);
field.set(obj, get(field.getName()));
}
......
}
}
在上述中,首先获取配置文件中已配置好的依赖关系,然后采用反射技术根据依赖关系进行创建相应的对象
5.其中ioc.properties的内容为:
departService=com.service.impl.DepartServiceImpl
6.查看入口方法:
public static void main(String[] args) {
UserServiceImpl user=new UserServiceImpl(); Container container=new Container();
container.inject(user);
user.printInfo(1);
}
7.查看结果:

总结:可以说IoC这个思想是一个很伟大的思想,现在很多大神甚至将它归为GoF中(因为IoC出现的比较晚,错过了GoF“四人组”的《Design Patterns: Elements of Reusable Object-Oriented Software》)。
控制反转(IoC)-解析与实现的更多相关文章
- 控制反转IOC的依赖注入方式
引言: 项目中遇到关于IOC的一些内容,因为和正常的逻辑代码比较起来,IOC有点反常.因此本文记录IOC的一些基础知识,并附有相应的简单实例,而在实际项目中再复杂的应用也只是在基本应用的基础上扩展而来 ...
- 控制反转(Ioc)和依赖注入(DI)
控制反转IOC, 全称 “Inversion of Control”.依赖注入DI, 全称 “Dependency Injection”. 面向的问题:软件开发中,为了降低模块间.类间的耦合度,提倡基 ...
- Spring框架系列(3) - 深入浅出Spring核心之控制反转(IOC)
在Spring基础 - Spring简单例子引入Spring的核心中向你展示了IoC的基础含义,同时以此发散了一些IoC相关知识点; 本节将在此基础上进一步解读IOC的含义以及IOC的使用方式.@pd ...
- 控制反转IoC简介
控制反转IoC简介 在实际的应用开发中,我们需要尽量避免和降低对象间的依赖关系,即降低耦合度.通常的业务对象之间都是互相依赖的,业务对象与业务对象.业务对象与持久层.业务对象与各种资源之间都存在这样或 ...
- 浅析“依赖注入(DI)/控制反转(IOC)”的实现思路
开始学习Spring的时候,对依赖注入(DI)——也叫控制反转(IOC)—— 的理解不是很深刻.随着学习的深入,也逐渐有了自己的认识,在此记录,也希望能帮助其他入门同学更深入地理解Spring.本文不 ...
- 控制反转IOC与依赖注入DI
理解 IOC http://www.cnblogs.com/zhangchenliang/archive/2013/01/08/2850970.html IOC 相关实例 的http:// ...
- 控制反转IOC与依赖注入DI【转】
转自:http://my.oschina.net/1pei/blog/492601 一直对控制反转.依赖注入不太明白,看到这篇文章感觉有点懂了,介绍的很详细. 1. IoC理论的背景我们都知道,在采用 ...
- 依赖注入(DI)和控制反转(IOC)
依赖注入(DI)和控制反转(IOC) 0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只 ...
- iOS控制反转(IoC)与依赖注入(DI)的实现
背景 最近接触了一段时间的SpringMVC,对其控制反转(IoC)和依赖注入(DI)印象深刻,此后便一直在思考如何使用OC语言较好的实现这两个功能.Java语言自带的注解特性为IoC和DI带来了极大 ...
随机推荐
- python装饰器大详解
1.作用域 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我要理解两点:a.在全局不能访问到局部定 ...
- TeamViewer——可以实现在手机上随时远程控制你的电脑
小编今天给大家推荐一款强大的远程控制软件——TeamViewer,可以让你的手机连接你自己的电脑,不管你身处何处,只要电脑和手机都能联网,那么你就可以在手机上控制你的电脑了.以下介绍下如何安装和使用方 ...
- Webpack 代码分离
Webpack 代码分离 代码分离是 webpack 中最引人注目的特性之一. 你可以把你的代码分离到不同的 bundle 中,然后你就可以去按需加载这些文件. 总的来说, webpack 分离可以分 ...
- 安装npm及cnpm(Windows)
[工具官网] Node.js : http://nodejs.cn/ 淘宝NPM: https://npm.taobao.org/ [安装步骤] 一.安装node.js 1.前往node.js官网下载 ...
- easygen通用代码生成框架[开源]
什么东东 用过mybatis的同学都知道,手工写mapper和xml是一件很痛苦的事儿,幸好官方提供了Mybatis-Generator,但是这家伙生成的东西不开放不方便修改,而且项目中的代码生成需求 ...
- Thread初探
Thread初探 前言 以前大家写的都是单线程的程序,全是在main函数中调用方法,可以清楚的看到它的效率是特别低的,就像python中使用单线程取爬一个网站,可以说能让你等的吐血,因为数据量实在太大 ...
- C#继承的执行顺序
自己对多态中构造函数.函数重载执行顺序和过程一直有些不理解,经过测试,对其中的运行顺序有了一定的了解,希望对初学者有些帮助. eg1: public class A { public A() { Co ...
- CSS Why
前面的话 在CSS学习目录中,已经详细地介绍了CSS如何使用.知其然,还要知其所以然.本文将介绍CSS各部分出现的原因,仅限个人理解,如有不妥,欢迎交流 Why CSS 早期的大多数网站标记几乎完全由 ...
- webpack前端工程化构建工具的使用
一.模块打包机 1.创建文件 在目标文件下建立一个src文件夹作为js代码区:作为例子,我创建了两个js文件,并利用commonJS规范require引入到index.js中: moduleA.js: ...
- vue1与vue2的路由 以及vue2项目大概了解
vue1的路由 1.设置根组件 Vue.extend() 2.设置局部组件 Vue.extend({template:"/home"}) 3.实例化路由 var route ...