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)的更多相关文章

  1. IOC 控制反转(Inversion of Control,英文缩写为IoC)

    在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 在这样的齿轮组中,因为是协同工作,如果有一个齿轮出了问题,就可能会影响到整个齿 ...

  2. 控制反转(Inversion of Control,英文缩写为IoC),另外一个名字叫做依赖注入(Dependency Injection,简称DI)

    控制反转(Inversion of Control,英文缩写为IoC),另外一个名字叫做依赖注入(Dependency Injection,简称DI),是一个重要的面向对象编程的法则来削减计算机程序的 ...

  3. 控制反转(Inversion of Control)之我的理解

    关于控制反转(Inversion of Control),在具体实现上也有许多其它的叫法,如依赖倒置(Dependency Inversion Principles, DIP).依赖注入(Depend ...

  4. 控制反转(IOC: Inverse Of Control) & 依赖注入(DI: Independence Inject)

    举例:在每天的日常生活中,我们离不开水,电,气.在城市化之前,我们每家每户需要自己去搞定这些东西:自己挖水井取水,自己点煤油灯照明,自己上山砍柴做饭.而城市化之后,人们从这些琐事中解放了出来,城市中出 ...

  5. C# 控制反转(IOC: Inverse Of Control) & 依赖注入(DI: Independence Inject)

    举例:在每天的日常生活中,我们离不开水,电,气.在城市化之前,我们每家每户需要自己去搞定这些东西:自己挖水井取水,自己点煤油灯照明,自己上山砍柴做饭.而城市化之后,人们从这些琐事中解放了出来,城市中出 ...

  6. Sring控制反转(Inversion of Control,Ioc)也被称为依赖注入(Dependency Injection,DI)原理用反射和代理实现

    首先我有一个数据访问层接口: public interface StudentDao { void save(Student stu); } 和实现类: 1.mysql实现类 public class ...

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

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

  8. 轻松学,浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI) 依赖注入和控制反转的理解,写的太好了。

    轻松学,浅析依赖倒置(DIP).控制反转(IOC)和依赖注入(DI) 2017年07月13日 22:04:39 frank909 阅读数:14269更多 所属专栏: Java 反射基础知识与实战   ...

  9. 依赖注入 DI 控制反转 IOC 概念 案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

随机推荐

  1. 转 java ClassLoader

    http://blog.csdn.net/xyang81/article/details/7292380 http://www.ibm.com/developerworks/cn/java/j-lo- ...

  2. docker Mac安装和使用

    1.安装docker brew cask install docker 2.安装后可以用命令查看版本 docker --version 3.build java 项目(jar) docker buil ...

  3. PostgreSQL-12-数据导入与导出

    1.数据导入 - COPY FROM CREATE DATABASE c04_datacleaning; \c c04_datacleaning 创建新的数据库 COPY table_name [ ( ...

  4. Flask (七) 部署

    阿里云部署Flask项目   部署Flask项目和部署Django项目基本一致,我们也使用uwsgi+nginx   我们在部署Django项目基础上部署Flask项目   1, 将uwsgi.ini ...

  5. 51nod 2133 排队接水

    Bryce1010模板 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=2133 #include <bits/std ...

  6. 洛谷 P1067 多项式输出

    P1067 多项式输出 模拟,很坑的那种 var i,n:longint; a:array[1..105] of integer; begin readln(n); for i:=1 to n+1 d ...

  7. python入门之lambda表达式、内置函数

    lambda 简单的函数就可以用lambda表达式 格式: abc = lambda a1,a2:a1+a2 其中,传参是a1和a2,返回值是a1+a2 内置函数 abs(a) #取绝对值 all(a ...

  8. JavaScript实现的9大排序算法

    笔试面试经常涉及各种算法,本文简要介绍常用的一些算法,并用JavaScript实现. 1.插入排序 1)算法简介 插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法.它的工作原 ...

  9. C#打开office文件,pdf文件和视频文件

    打开office文件 1 需要从网站下载dsoframer.ocx文件 2 把dsoframer.ocx文件复制到c:\windows\system32目录下 开始->运行->regsvr ...

  10. onpageshow 监听页面是否是缓存页面

    需求:点击A页面跳转至B页面,在B页面点击手机物理回退键或者history.back回退时,需要在A页面判断当前页面是否是回退回来的页面,而不是新加载的.这里用到一个 onpageshow 事件. 定 ...