IoC是什么

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:

●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

●为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

用图例说明一下,传统程序设计如图2-1,都是主动去创建相关对象然后再组合起来:

图2-1 传统应用程序示意图

当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了,如图2-2所示:

图2-2有IoC/DI容器后程序结构示意图

1.1.2  IoC能做什么

IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

2.1.3  IoC和DI

DI—Dependency Injection,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

●谁依赖于谁:当然是应用程序依赖于IoC容器;

●为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;

●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;

●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。

IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

注:如果想要更加深入的了解IoC和DI,请参考大师级人物Martin Fowler的一篇经典文章《Inversion of Control Containers and the Dependency Injection pattern》,原文地址:http://www.martinfowler.com/articles/injection.html。

IOC容器就是具有依赖注入功能的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需在代码中new相关的对象,应用程序由IOC容器进行组装。

spring IOC管理的对象,我们称为bean。bean就是spring容器初始化,装配,及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别。那IOC如何实例化bean、管理bean之间的依赖关系?这些就需要配置元数据。

写个hello world(我用的是maven)

pom.xml

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.3.4.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>jdom</groupId><artifactId>jdom</artifactId><version>1.1</version>
</dependency>

helloInter.java

public interface helloInter {public void sayHello();
}

helloImpl.java

public class helloImpl implements helloInter{public void sayHello() {// TODO Auto-generated method stubSystem.out.println("Hello World!!!");}}

hello.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  http://www.springframework.org/schema/context                http://www.springframework.org/schema/context/spring-context-4.0.xsd"><!-- id 表示你这个组件的名字,class表示组件类 --><bean id="hello" class="com.lj.testspring.chapter.helloImpl"></bean>
</beans>  

helloTest.java

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class helloTest {@Testpublic void testHelloWorld() {  //1、读取配置文件实例化一个IoC容器  ApplicationContext context = new ClassPathXmlApplicationContext("hello.xml");  //2、从容器中获取Bean,注意此处完全“面向接口编程,而不是面向实现”  helloInter helloApi = context.getBean("hello", helloInter.class);  //3、执行业务逻辑
                  helloApi.sayHello();  }  }

运行,可以看出输出一个hello World。

在spring IOC容器的代表就是org.springframework.beans包中的BeanFactory接口,BeanFactory接口提供了IOC容器最基本功能,而org.springframework.context包下的ApplicationContext接口扩展了BeanFactory,还提供了与Spring AOP集成,国际化处理,事件传播及提供不同层次的context实现。简单说,BeanFactory提供了IOC容器最基本功能,而ApplicationContext则增加了更多支持企业级功能支持。ApplicationContext完全继承BeanFactory,因而BeanFactory所具有的语义也适用于ApplicationContext。

容器实现一览:

XmlBeanFactory:BeanFactory实现,提供基本的IoC容器功能,可以从classpath或文件系统等获取资源;
(1) File file = new File("fileSystemConfig.xml");
Resource resource = new FileSystemResource(file);
BeanFactory beanFactory = new XmlBeanFactory(resource);
(2)
Resource resource = new ClassPathResource("classpath.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);

ClassPathXmlApplicationContext:ApplicationContext实现,从classpath获取配置文件;
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath.xml");

FileSystemXmlApplicationContext:ApplicationContext实现,从文件系统获取配置文件。
BeanFactory beanFactory = new FileSystemXmlApplicationContext("fileSystemConfig.xml");

ApplicationContext接口获取Bean方法简介:
• Object getBean(String name) 根据名称返回一个Bean,客户端需要自己进行类型转换;
• T getBean(String name, Class<T> requiredType) 根据名称和指定的类型返回一个Bean,客户端无需自己进行类型转换,如果类型转换失败,容器抛出异常;

• T getBean(Class<T> requiredType) 根据指定的类型返回一个Bean,客户端无需自己进行类型转换,如果没有或有
多于一个Bean存在容器将抛出异常;
• Map<String, T> getBeansOfType(Class<T> type) 根据指定的类型返回一个键值为名字和值为Bean对象的 Map,
如果没有Bean对象存在则返回空的Map。

让我们来看下IoC容器到底是如何工作。在此我们以xml配置方式来分析一下:

一、准备配置文件:就像前边Hello World配置文件一样,在配置文件中声明Bean定义也就是为Bean配置元数据。

二、由IoC容器进行解析元数据: IoC容器的Bean Reader读取并解析配置文件,根据定义生成BeanDefinition配置元数据对象,IoC容器根据BeanDefinition进行实例化、配置及组装Bean。

三、实例化IoC容器:由客户端实例化容器,获取需要的Bean。

Spring IoC是什么相关推荐

  1. spring IOC创建对象方式

    spring IOC创建对象方式 通过无参构造来创建 验证方法: 创建实体类: public class User {private String name;public User() {System ...

  2. spring ioc原理分析

    spring ioc原理分析 spring ioc 的概念 简单工厂方法 spirng ioc实现原理 spring ioc的概念 ioc: 控制反转 将对象的创建由spring管理.比如,我们以前用 ...

  3. Spring IoC是如何进行依赖注入的

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 依赖注入(DI) DI(Dependency Injection) ...

  4. 面试被问烂的 Spring IOC(求求你别再问了)

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 作者:莫那·鲁道 链接:http://thinkinjava.cn 广义的 IOC IoC(Inv ...

  5. spring根据名称获取bean_带你从零开始手写 spring ioc 框架,深入学习 spring 源码

    IoC Ioc 是一款 spring ioc 核心功能简化实现版本,便于学习和理解原理. 创作目的 使用 spring 很长时间,对于 spring 使用非常频繁,实际上对于源码一直没有静下心来学习过 ...

  6. 还不懂spring IOC核心原理?200行代码带你手撸一个

    Spring做为Java企业级应用的开源开发框架,早已成为Java后端开发事实上的行业标准,无数的公司选择Spring作为基础的开发框架. 使用Spring框架的人一定都听过Spring的IoC(控制 ...

  7. 头条一面:Spring IOC容器中只存放单例Bean吗?

    最近,很多小伙伴出去面试,感觉自己面的不是很理想,回来后,不少小伙伴把面试题做了记录发给我,让我给大家解析下,然后发出来.当我看到这些面试题时,快速在脑海中构建起了整个知识体系,从基础到框架.从分布式 ...

  8. 谈谈对Spring IOC的理解

    2019独角兽企业重金招聘Python工程师标准>>> 学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人 ...

  9. Spring点滴一:Spring Ioc 容器

    Spring 容器: Spring 容器是Spring框架的核心.Spring容器将创建Bean对象实例,把它们联系在一起,配置它们,并管理它们整个生命周期从创建到销毁.Spring 容器通过依赖注入 ...

  10. MyEclipse Spring 学习总结一 Spring IOC容器

    一.Spring IOC容器---- Spring AllicationContext容器 程序的结构如下: 1.首先在MyEclipse 创建创建Java Project 2.创建好后,添加spin ...

最新文章

  1. 局域网语音通话demo
  2. jQuery 实现上下,左右滑动
  3. 我为什么要写FansUnion个人官网-BriefCMS-电子商务malling等系统
  4. 印发 指南 通知_通知设计的综合指南
  5. .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了
  6. Java面试基础知识(1)
  7. apache http server 停止工作_宝塔apache启动失败:报错 AH00526: Syntax error on line 解决方案...
  8. 如何使用Idea导入jar包
  9. 抓住数字经济机遇 新华三助力客户加速转型
  10. 源码生成网站,开发帮助网站
  11. JAVA汉化教程 自带eclipse即可无需外部工具
  12. 金蝶中间件公司CTO袁红岗
  13. jay chou歌词 文本下载数据下载
  14. style.left不起作用的问题
  15. 0x0F1AFD76 (libcocos2d.dll) (Plane.exe 中)处有未经处理的异常: 0xC0000005: 读取位置 0x00000018 时发生访问冲突。
  16. Word2013使用 插入题注的方式为word自带编辑器编辑的公式进行编号
  17. 开发客户的渠道+方法
  18. 矩阵理论——直和与投影
  19. 逻辑学在计算机中的应用论文,逻辑学导论论文范文
  20. IDEA设置文件抬头

热门文章

  1. 饱受争议的闪电网络,能在2020年迎来大爆发吗?
  2. 软件生命周期管理系统ALM配置说明(二)
  3. dos命令(转东转西)
  4. 个人总结出来的git仓库迁移方案
  5. 四少女火爆外网!ControlNet组合拳效果惊人,颠覆AI绘画游戏规则
  6. ptp精准时间协议_网络时钟同步协议– NTP, PTP – 默默的点滴
  7. CentOS网络时钟同步协议-- NTP, PTP
  8. 使用java进行excel的读写,两种excel的区别以及easyexcel的使用
  9. 同构图异构图二部图区别
  10. 一文搞懂积分不等式证明(积分证明题总结笔记3/3)