一 Ioc基础

1.什么是Ioc?

  Ioc(Inversion of Control)既控制反转,Ioc不是一种技术,而是一种思想,在Java开发中意味着将设计好的对象交给容器来进行控制,并不是像传统的程序一样在对象内部进行创建。

2.如何理解Ioc?

  在传统的程序中,当某个Java对象(调用者)需要调用另一个Java对象(被调用者,既被依赖对象)时,调用者通常会采用“new 调用者”的代码方式来创建对象。

  理解Ioc的关键在于要理解“谁控制谁,控制什么,为何是反转,哪些方面反转了”

  * 谁控制谁,控制什么:在传统的Java程序中,我们通常都是在一个类的内部直接创建一个对象(使用new),这样就是程序主动的去创建一个对象,控制权在程序,而在spring的Ioc中,是由一个专门的容器来创建这些对象,控制权不在程序了。谁控制谁?Ioc容器控制了对象。控制什么?Ioc容器主要控制了一个类对外部资源(对象,文件)的获取。

  *为何是反转,哪些方面反转了:

   有了反转,必定由正转:

   正转:在传统的程序中,是由自己在一个对象(一个类中)直接去创建一个1依赖对象,这就是正转。

   反转:反转就是由Ioc容器来创建对象并且给类注入此对象。

   为何是反转?因为是由容器来创建并且帮助注入依赖对象,对象并没有直接去创建(new)一个对象而是被动的接受依赖对象,所以是反转。

   哪些方面反转了?依赖对象的获取被反转了。

                  

                    传统应用程序示意图

                                  使用Ioc容器后的程序结构示意图

3.Ioc的优点

  Ioc不是一种技术,而是一种思想,是一个重要的面向对象的编程法则,他能指导我们如何设计出松耦合,更优良的程序,传统的应用程序是我们在类的内部主动创建依赖对象,从而导致类与类之间的高耦合,难以测试,有了Ioc容器后,由容器来创建和查找依赖对象,并给对象注入依赖对象,所以对象与对象之间是松散耦合,方便测试,利于功能复用。

  Ioc对编程带来的最大改变不是代码上,而是思想上,应用程序原本是老大,要获取什么资源都是主动的去创建,但是在Ioc思想种,应用程序就变动被动了,被动地等待Ioc容器来创建并注入它所需的资源。

  Ioc容器很好的体现了面向对象的设计法则之一:好莱坞法则“别找我们,我们找你”,即由Ioc容器来创建并注入对象,而不是由对象来找。

  

二 依赖注入

1.什么是依赖注入(DI)?

  依赖注入(DI)是控制反转(Ioc)的含义相同,只不过是从不同的角度来看待。

2.依赖注入的目的?

  依赖注入的目的并非是为系统带来更多的功能,而是为了提高组件的重用率,并为系统搭建一个灵活的可扩展的平台。

3.理解DI的关键?

  理解DI的关键是“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么?”

  *谁依赖谁:应用程序依赖Ioc容器。

  *为什么需要依赖:应用程序需要Ioc容器来提供对象所需的资源。

  *谁注入谁:Ioc容器注入应用程序所需的依赖对象

  *注入了什么:注入了某个对象所需的外部资源。

4.Ioc和DI的关系

  Ioc和DI相当于一回事,只不过是看待问题的角度不同:

  Ioc:spring反向控制应用程序所需的资源;

  DI:应用程序依赖spring为其提供资源

5.依赖注入的方式

  依赖注入的作用是在使用spring框架时,动态地将其所依赖的对象注入到Bean组件中,其实现方法有两种:

  ☞ 属性setter方法注入:指的是spring容器使用setter方法注入被依赖的实例。通过调用无参构造器或者无参静态工厂方法实例化Bean后,调用该bean的setter方法,即可实现基于setter方法的依赖注入。

  ☞ 构造方法注入:指spring容器使用构造方法注入被依赖的实例。基于构造方法的依赖注入是通过调用带参数的构造方法来实现,每个参数代表着一个依赖。

  下面是使用setter方法来注入依赖对象

(1)创建一个UserDao接口,该接口中有一个方法say方法

package com.itheima.ioc;

public interface  UserDao {
public void say();
}

  (2)创建一个UserDaoImpl的类,该类实现了接口UserDao

package com.itheima.ioc;

public class UserDaoImpl implements UserDao {
@Override
public void say() {
System.out.println("UserDao say hello Word!"); }
}

  (3)创建一个UserService接口

package com.itheima.ioc;

public interface UserService {
public void say();
}

 (4)创建一个UserServiceImpl类,该类实现了UserService 接口,类中有一个属性UserDao,并且有一个方法setter,该方法是用于Ioc容器给UserServiceImpl注入UserDao对象。

package com.itheima.ioc;

public class UserServiceImpl implements UserService {

    //声明UserDao属性
private UserDao UserDao; //添加UserDao属性的setter方法
public void setUserDao(UserDao userDao) {
UserDao = userDao;
} //实现接口中的方法
@Override
public void say() {
//调用userDao的方法
this.UserDao.say();
System.out.println("userService say hello World!");
}
}

  

  (5)配置applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"> <!-- 将指定的类配置给Spring,让Spring创建其对象的实例 -->
<bean id="userDao" class="com.itheima.ioc.UserDaoImpl"/> <!-- 添加一个id为userService的bean -->
<bean id="userService" class="com.itheima.ioc.UserServiceImpl">
<!-- 将id为userDao的bean实例注入到user Service实例中 -->
<property name="userDao" ref="userDao"/>
</bean>
</beans>

  <property>元素是<bean>元素的子元素,它用于调用Bean实例中的setUserDao()方法完成属性赋值,从而实现依赖注入。其name属性表示Bean实例中相应属性名,ref属性用于指定属性值。

  (6)Test测试类

package com.itheima.ioc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DITest {
public static void main(String[] args) {
//1.初始化spring容器,加载配置文件
ApplicationContext applicationContext=
new ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过容器来获取UserService实例
UserService userService=(UserService) applicationContext.getBean("userService");

//3.调用实例中的方法
userService.say();
}
}

  (7)程序结果

  

三 Ioc容器

  容器中的两种表示形式:BeanFactory 和ApplicationContext

  springIoc把BeanFactory的实现当作低级容器,把ApplicationContext的实现当作高级容器

1.两个容器之间的区别:

  BeanFactory:容器在启动的时候并不会实例化bean,只有当用户调用getBean时才会对配置好的bean进行实例化。

  ApplicationContext容器:当容器启动时,容器就已经实例化好了所有配置的bean。

2.如何延迟实例化:

  对于在ApplicationContext容器启动便进行了实例化,可以通过两种方法来延迟实例化:

  ☞ 可以在bean元素配置lazy-init=true来让bean延迟实例化;

  ☞ 可以在beans元素里配置lazy-init=true来让这个beans里的所有bean都延迟实例化;

3.如何选择延迟化和非延迟化

  ☞ 对于系统资源比较少的可以使用延迟实例化;

  ☞ 对于web应用,一般选择迫切实例化;

  ☞ 在web应用中,我们一般把比较耗时的事情放在系统启动的时候完成;

spring学习之依赖注入DI与控制反转IOC的更多相关文章

  1. PHP依赖注入(DI)和控制反转(IoC)详解

    这篇文章主要介绍了PHP依赖注入(DI)和控制反转(IoC)的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程 ...

  2. 依赖注入(DI)和控制反转(IOC)

    依赖注入(DI)和控制反转(IOC) 0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只 ...

  3. 依赖注入(DI)和控制反转(IOC)的理解,写的太好了。

    学习过spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  4. 【串线篇】依赖注入DI与控制反转IOC

    DI&IOC 在spring框架中DI与IOC说的其实是一回事 一句话:本来我接受各种参数来构造一个对象,现在只接受一个参数——已经实例化的对象. 也就是说我对对象的『依赖』是注入进来的,而和 ...

  5. 轻松理解 Java开发中的依赖注入(DI)和控制反转(IOC)

    前言 关于这个话题, 网上有很多文章,这里, 我希望通过最简单的话语与大家分享. 依赖注入和控制反转两个概念让很多初学这迷惑, 觉得玄之又玄,高深莫测. 这里想先说明两点: 依赖注入和控制反转不是高级 ...

  6. 话说 依赖注入(DI) or 控制反转(IoC)

    科普:首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程序间的耦合,鄙人学习了一下,看TP官网还没有相关的文章,就写下这篇拙作介绍一下这种设计模式,希望能为TP社区贡献一些 ...

  7. ASP.NET MVC进阶之路:深入理解依赖注入(DI)和控制反转(IOC)

    0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点.在程序运行过程中,客户 ...

  8. PHP 依赖注入(DI) 和 控制反转(IoC)

    要想理解 PHP 依赖注入 和 控制反转 两个概念,就必须搞清楚如下的两个问题: DI —— Dependency Injection 依赖注入 IoC —— Inversion of Control ...

  9. 聊一聊PHP的依赖注入(DI) 和 控制反转(IoC)

    简介 IoC Inversion of Control 控制反转DI Dependency Injection 依赖注入 依赖注入和控制反转说的实际上是同一种东西,它们是一种设计模式,这种设计模式用来 ...

随机推荐

  1. 11.swoole学习笔记--进程信号触发器

    <?php //触发函数--异步执行 swoole_process::signal(SIGALRM,function(){ ; echo "$i \n"; $i++; ){ ...

  2. 用 Python 编写一个天气查询应用 pyqt5

    ​ 效果预览: !   ​ 一.获取天气信息 使用python获取天气有两种方式. 1)是通过爬虫的方式获取天气预报网站的HTML页面,然后使用xpath或者bs4解析HTML界面的内容. 2)另一种 ...

  3. 069-PHP数组下标

    <?php $arr=array(98,'hello',67,'A',85,NULL); //定义一个数组 $x=0; //定义三个作为下标的变量 $y=3; $z=5; echo " ...

  4. 054-for循环

    <?php for($i=1;$i<=5;$i++){ echo "$i<br />"; //循环体 } ?>

  5. 前端第四篇---前端基础之jQuery

    前端第四篇---前端基础之jQuery 一.jQuery介绍 二.jQuery对象 三.jQuery基础语法 四.事件 五.动画效果 六.补充each 一.jQuery简介 1.jQuery介绍 jQ ...

  6. vim使用技巧(常用指令)

    1. vim基础操作 vim是从 vi 发展出来的一个文本编辑器 .代码补完.编译及错误跳转等做了一些增强 1.1 进入编辑模式 命令 含义 i和I i在光标前插入,I在行首插入. a和A a在光标后 ...

  7. 将已有微信小程序转换为多端应用

    文档地址 https://nervjs.github.io/taro/

  8. Oracle 中多个字段显示成一列

    SELECT COALESCE(A,B,C,'NA') FROM XXXXX --判断A若为空则取B,B为空这取C,C为空则取默认值'NA'

  9. RGB转到HSV色彩空间转换

    原文链接:https://blog.csdn.net/lsg19920625/article/details/78416649

  10. Java基础——HashTable源码分析

    HashTable是基于哈希表的Map接口的同步实现 HashTable中元素的key是唯一的,value值可重复 HashTable中元素的key和value不允许为null,如果遇到null,则返 ...