【Java_Spring】控制反转IOC(Inversion of Control)
1. IOC的概念
控制反转IoC(Inversion of Control)是一种设计思想,而DI(依赖注入)是实现IoC的一种方法。在没有使用IOC的程序中,对象间的依赖关系是靠硬编码的方式实现的。引入IOC后对象的创建由程序自己控制的,控制反转即将对象的创建交给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

IoC是Spring框架的核心内容,在IOC容器中一切对象皆为Bean组件。IOC容器通过读取XML配置文件中的Bean信息,产生每个Bean实例。也可以使用注解,新版本的Spring也可以零配置实现IoC。
2. 使用XML配置文件实现依赖注入
/**人*/
public abstract class Person {
public String name;
}
/**学生*/
public class Student extends Person {
/**身高*/
public int height;
/**有参构造方法*/
public Student(String name,int height){
this.name=name;
this.height=height;
}
@Override
public String toString() {
return "Student{" + "height=" + height+",name="+name +'}';
}
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class School {
public static void main(String[] args) {
//IoC容器
ApplicationContext ctx=new ClassPathXmlApplicationContext("beans02.xml");
//从容器中获取对象
Person tom=ctx.getBean("tom",Person.class);
System.out.println(tom);
}
}
2.1 通过参数名来注入
<?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.xsd">
<bean id="tom" class="spring02.Student">
<constructor-arg name="name" value="张柏川"></constructor-arg>
<constructor-arg name="height" value="195"></constructor-arg>
</bean>
</beans>
2.2 通过参数下标来注入
<bean id="rose" class="spring02.Student">
<constructor-arg index="0" value="张柏芝"></constructor-arg>
<constructor-arg index="1" value="196"></constructor-arg>
</bean>
2.3 通过属性赋值
<bean id="jack" class="spring02.Student">
<property name="name" value="张三"></property >
<property name="height" value="195"></property >
</bean>
注意:这种通过property 注入的方式,只能对有构造器(即有set和get方法)的属性注入,对与没有构造器的属性不能用这种方式注入
特殊情况:若注入的属性为引用类型,则通过ref指定属性值
Student.java
/**学生*/
public class Student {
/**姓名*/
String name;
/**身高*/
public int height;
/**地址*/
public Address address;
/**有参构造方法*/
public Student(String name,int height){
this.name=name;
this.height=height;
}
/**有参构造方法*/
public Student(String name,int height,Address address){
this.name=name;
this.height=height;
this.address=address;
}
@Override
public String toString() {
return "Student{" + "height=" + height+",name="+name +'}'+address;
}
}
Address.java
/**地址*/
public class Address {
/**国家*/
private String country;
/**城市*/
private String city;
public Address() {
}
public Address(String country, String city) {
this.country = country;
this.city = city;
}
@Override
public String toString() {
return "Address{" +
"country='" + country + '\'' +
", city='" + city + '\'' +
'}';
} public String getCountry() {
return country;
} public void setCountry(String country) {
this.country = country;
} public String getCity() {
return city;
} public void setCity(String city) {
this.city = city;
}
}
通过配置文件注入引用类型属性
<?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.xsd">
<bean name="zhuhai" class="spring02.Address">
<property name="country" value="中国"></property>
<property name="city" value="珠海"></property>
</bean>
<bean id="tom" class="spring02.Student">
<constructor-arg name="name" value="张柏川"></constructor-arg>
<constructor-arg name="height" value="195"></constructor-arg>
<constructor-arg name="address" ref="zhuhai"></constructor-arg>
</bean>
<bean id="rose" class="spring02.Student">
<constructor-arg index="0" value="张柏芝"></constructor-arg>
<constructor-arg index="1" value="196"></constructor-arg>
<constructor-arg index="2" ref="zhuhai"></constructor-arg>
</bean>
</beans>
测试代码:
package spring02;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class School {
public static void main(String[] args) {
//IoC容器
ApplicationContext ctx=new ClassPathXmlApplicationContext("bookbean01.xml","beans02.xml");
//从容器中获取对象
Person tom=ctx.getBean("tom",Person.class);
Person rose=ctx.getBean("rose",Person.class);
//Address zhuhai=ctx.getBean("zhuhai",Address.class);
System.out.println(tom);
System.out.println(rose);
}
}
2.4 scope属性控制从容器中取回对象的作用域
从容器中取回的对象默认是单例的
Person roseA=ctx.getBean("rose",Person.class);
Person roseB=ctx.getBean("rose",Person.class);
//Address zhuhai=ctx.getBean("zhuhai",Address.class);
System.out.println(tom);
System.out.println(roseA==roseB);
运行结果:

scope属性可取值如下:

scope属性取值prototype的实例:
<bean id="rose" class="spring02.Student" scope="prototype">
<constructor-arg index="0" value="张柏芝"></constructor-arg>
<constructor-arg index="1" value="196"></constructor-arg>
<constructor-arg index="2" ref="zhuhai"></constructor-arg>
</bean>
//从容器中获取对象
Person tom=ctx.getBean("tom",Person.class);
Person roseA=ctx.getBean("rose",Person.class);
Person roseB=ctx.getBean("rose",Person.class);
//Address zhuhai=ctx.getBean("zhuhai",Address.class);
System.out.println(tom);
System.out.println(roseA==roseB);
运行结果:

2.5 lazy-init属性控制Bean的延迟实例化
ApplicationContext默认是在启动时将所有 singleton bean提前实例化。 通常这样的提前实例化方式是好事,因为配置中或者运行环境的错误就会被立刻发现,否则可能要花几个小时甚至几天。如果你不想这样,你可以将单例bean定义为延迟加载防止它提前实例化。延迟初始化bean会告诉Ioc容器在第一次需要的时候才实例化而不是在容器启动时就实例化。
实例:
<bean id="lazytom" class="spring_IoC.dao.Student" lazy-init="true" scope="prototype">
<constructor-arg name="name" value="张柏川"></constructor-arg>
<constructor-arg name="height" value="195"></constructor-arg>
</bean>
public static void main(String[] args) {
//IoC容器
ApplicationContext ctx =new ClassPathXmlApplicationContext("applicationContext.xml");
try {
Thread.sleep(2000);
//从容器中获取对象
Person tom1=ctx.getBean("lazytom",Person.class);
System.out.println("tom1初始化了");
Thread.sleep(2000);
Person tom2=ctx.getBean("lazytom",Person.class);
System.out.println("tom2初始化了");
System.out.println(tom1==tom2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
结果:
tom1初始化了
tom2初始化了
false
【Java_Spring】控制反转IOC(Inversion of Control)的更多相关文章
- IOC 控制反转(Inversion of Control,英文缩写为IoC)
在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 在这样的齿轮组中,因为是协同工作,如果有一个齿轮出了问题,就可能会影响到整个齿 ...
- 控制反转(Inversion of Control,英文缩写为IoC),另外一个名字叫做依赖注入(Dependency Injection,简称DI)
控制反转(Inversion of Control,英文缩写为IoC),另外一个名字叫做依赖注入(Dependency Injection,简称DI),是一个重要的面向对象编程的法则来削减计算机程序的 ...
- 控制反转(Inversion of Control)之我的理解
关于控制反转(Inversion of Control),在具体实现上也有许多其它的叫法,如依赖倒置(Dependency Inversion Principles, DIP).依赖注入(Depend ...
- 控制反转(IOC: Inverse Of Control) & 依赖注入(DI: Independence Inject)
举例:在每天的日常生活中,我们离不开水,电,气.在城市化之前,我们每家每户需要自己去搞定这些东西:自己挖水井取水,自己点煤油灯照明,自己上山砍柴做饭.而城市化之后,人们从这些琐事中解放了出来,城市中出 ...
- C# 控制反转(IOC: Inverse Of Control) & 依赖注入(DI: Independence Inject)
举例:在每天的日常生活中,我们离不开水,电,气.在城市化之前,我们每家每户需要自己去搞定这些东西:自己挖水井取水,自己点煤油灯照明,自己上山砍柴做饭.而城市化之后,人们从这些琐事中解放了出来,城市中出 ...
- Sring控制反转(Inversion of Control,Ioc)也被称为依赖注入(Dependency Injection,DI)原理用反射和代理实现
首先我有一个数据访问层接口: public interface StudentDao { void save(Student stu); } 和实现类: 1.mysql实现类 public class ...
- 依赖注入(DI)和控制反转(IOC)的理解,写的太好了。
学习过spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...
- 轻松学,浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI) 依赖注入和控制反转的理解,写的太好了。
轻松学,浅析依赖倒置(DIP).控制反转(IOC)和依赖注入(DI) 2017年07月13日 22:04:39 frank909 阅读数:14269更多 所属专栏: Java 反射基础知识与实战 ...
- 依赖注入 DI 控制反转 IOC 概念 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
随机推荐
- tpc-ds99 工具使用
安装部署 tpc-ds-99 工具 解压文件 unzip tpc-ds-tool.zip 进入目录 cd v2.3.0/tools 拷贝Makefile文件 cp Makefile.suite Mak ...
- spark sql 对接 HDFS
上一篇博客我向大家介绍了如何快速地搭建spark run on standalone,下面我将介绍saprk sql 如何对接 hdfs 我们知道,在spark shell 中操作hdfs 上的数据是 ...
- 两段代码实现vue路由懒加载
const Foo = () => import('./Foo.vue') const router = new VueRouter({ routes: [ { path: '/foo', co ...
- 证书重复冲突问题:Command /usr/bin/codesign failed with exit code 1
打开钥匙串 查看是否有两个identifier为相同 的证书,显然导证书的时候不知道怎么把证书导进了系统帐号,并且还重复了.把重复的证书删除就行了.
- 并发编程协程(Coroutine)之Gevent
并发编程协程之Gevent Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate r ...
- UVa12186:Another Crisis(树形DP)
一道简单的树形DP送给你. A couple of years ago, a new world wide crisis started, leaving many people with econo ...
- 洛谷 P2662 牛场围栏
做法是这样的: 首先暴力把所有可能的边长搞出来..(当然<=0的不要) 排序边长+去重, 当且仅当可行边长里面有1时,任何长度都能取到,输出-1 当且仅当所有可行边长的gcd大于1时,不能取到的 ...
- Influxdb 时序数据库 windows 安装
Influxdb 是一款比较火爆的时序数据库,本文介绍如何在 windows 平台下安装. 1.场景: windows 平台的 influxdb 似乎只支持单机非windows 服务的安装方式 适用于 ...
- Springboot下事务管理的简单使用
关于事务管理的概念这里就不多介绍了,在我的博客“JDBC事务之理论篇”中也有介绍. 关于Spring的事务管理,主要是通过事务管理器来进行的.这里看个Spring事务管理的接口图:(来自博客https ...
- Spark Mllib里如何删除每一条数据中所有的双引号“”(图文详解)
不多说,直接上干货! 具体,见 Hadoop+Spark大数据巨量分析与机器学习整合开发实战的第13章 使用决策树二元分类算法来预测分类StumbleUpon数据集