控制反转——Spring通过一种称作控制反转(IOC)的技术促进了低耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。

  下面简单通过实例来看一下控制反转的好处:

  首先先定义一个Cat.java类

package com.model;

public class Cat  {
private String name="kitty";
private int age=2; public void sleep(){
System.out.println(name+"猫睡了");
}
}

再定义一个main函数的类调用Cat

public class Test {

    public static void main(String[] args) {
Cat p = new Cat();
p.sleep();
}

  这样会输出 kitty猫睡了 这句话。

  

  首先我们来分析一下代码:在main中new 一个Cat,其实这样Cat的名字和年龄就已经固定了

  重点来了:如果我要换个猫呢?那么new的对象就要从Cat里面修改。这岂不是非常麻烦的事而且破环了项目的一体性。实际上现在工作的控制权并不在main中而是在JavaWork中,而正确的解决方法是将控制权交到mian中!

  要想实现控制反转:

  首先定义一个接口,让所有的宠物都通过这个接口

package com.model;

public interface IPet {
public String getName();
public void setName(String name);
public void sleep();
}

  再将Cat类添加实现方法

package com.model;

public class Cat implements IPet {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void sleep(){
System.out.println(name+"猫睡了");
}
}

  再造一个Dog类实现IPet接口

package com.model;

public class Dog implements IPet {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
} public Dog(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void sleep(){
System.out.println(name+"狗睡了");
}
}

  再做一个Human类添加另外一个方法,其中包含了IPet这个接口实现的Cat和Dog类的feed方法

package com.model;

public class Human  {
private IPet pet;
public IPet getPet() {
return pet;
}
public void setPet(IPet pet) {
this.pet = pet;
}
public void feed(){
System.out.println("正在喂养"+pet.getName());
pet.sleep();
}
}

  在这里,我们采用Spring的xml配置来实现控制反转(beans.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.xsd"> <bean id="pet1" class="com.model.Dog">
<constructor-arg name="name" value="wang"></constructor-arg>
<constructor-arg name="age" value="2"></constructor-arg>
</bean> <bean id="pet2" class="com.model.Cat">
<property name="name" value="miao"></property>
<property name="age" value="3"></property>
</bean> <bean id="pet3" class="com.model.Mouse" init-method="born"> </bean>
<bean id="human" class="com.model.Human" >
<property name="pet" ref="pet1"></property>
</bean> </beans>

  最后做一个带有main函数的测试类

package com.model;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) {
// IPet p = new Dog();
// p.sleep();
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
IPet p1=(IPet)context.getBean("pet1");
IPet p2=(IPet)context.getBean("pet2");
IPet p3=(IPet)context.getBean("pet3");
p1.sleep();
p2.sleep();
p3.sleep(); Human h = (Human)context.getBean("human");
h.feed();
} }

  此时的输出结果为

wang狗睡了
miao猫睡了
laoshu鼠睡了
正在喂养wang
wang狗睡了

  因为在beans.xml中定义的pet1狗叫wang年龄2,pet2猫叫miao年龄3,human只喂养了pet1狗,再调用pet1的sleep,然后可以发现,我定义了一个pet3的老鼠,但是我并没有给它名字和年龄,依然能出来结果,是因为调用了init-method="born"方法,这个写法的意思是调用此类内部的方法born,看一下Mouse.java类的写法:

package com.model;

public class Mouse implements IPet{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void born(){
name="laoshu";
age=1;
}
public void sleep(){
System.out.println(name+"鼠睡了");
}
}

  是不是一目了然。所以如果要换个宠物来养,那么直接修改beans.xml里面human的ref里面的定义的bean的id就好了。

Spring IOC(控制反转)详解及示例的更多相关文章

  1. 学习Spring IOC控制反转和DI依赖注入总结

    30岁的小曹,20岁的身体,还在坚持在能力允许控制范围内22点睡觉,5点起床锻炼身体,好好学习,除了加班或者像今天这样的深夜,再一次写已经有X百万人写过的 spring Ioc 的总结博客. 一.IO ...

  2. spring2.5IOC控制反转详解

    spring2.5IOC控制反转详解 19. 五 / J2EE / 一条评论   基本的代码结构 1 IOC包下 基本的spring创建对象 将类添加到配置文件中,由容器创建. Source code ...

  3. Spring框架系列(6) - Spring IOC实现原理详解之IOC体系结构设计

    在对IoC有了初步的认知后,我们开始对IOC的实现原理进行深入理解.本文将帮助你站在设计者的角度去看IOC最顶层的结构设计.@pdai Spring框架系列(6) - Spring IOC实现原理详解 ...

  4. Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程

    上文,我们看了IOC设计要点和设计结构:紧接着这篇,我们可以看下源码的实现了:Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的. ...

  5. Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)

    上文,我们看了IOC设计要点和设计结构:以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的:容器中存放的是Bean的定义即Be ...

  6. Spring IoC控制反转创建实例

    Spring IoC控制反转创建实例写一个配置文件beans.xml,配置文件的约束可以访问:完整链接:https://repo.spring.io/libs-release-local/org/sp ...

  7. Spring IoC @Autowired 注解详解

    前言 本系列全部基于 Spring 5.2.2.BUILD-SNAPSHOT 版本.因为 Spring 整个体系太过于庞大,所以只会进行关键部分的源码解析. 我们平时使用 Spring 时,想要 依赖 ...

  8. Spring IoC 公共注解详解

    前言 本系列全部基于 Spring 5.2.2.BUILD-SNAPSHOT 版本.因为 Spring 整个体系太过于庞大,所以只会进行关键部分的源码解析. 什么是公共注解?公共注解就是常见的Java ...

  9. Spring IOC(控制反转)思想笔记

    Spring IOC(控制反转)思想笔记 IOC控制反转基本理念就是将程序控制权从程序员手中交给用户自定义,从而避免了因为用户一个小需求的变化使得程序员需要改动大量代码. 案例 如果按照之前javaw ...

随机推荐

  1. Vue风格指南总结及对应ESLint规则配置

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10906951.html,多谢,=.=~ 必要的:规避错误: 强烈推荐:改善可读性和开发体验: 推 ...

  2. asp页面无法访问,可尝试开始SQL Server等服务

    存在问题 asp页面的英文提示,翻译后为: "一个错误发生在服务器在处理URL.请联系系统管理员(管理人).如果您是系统管理员,请点击这里了解更多关于这个错误."   解决方案 请 ...

  3. 1003: Redraiment的遭遇

    1003: Redraiment的遭遇 Time Limit: 1000 Sec  Memory Limit: 128 MBSubmit: 456  Solved: 158[Submit][Statu ...

  4. Chunky Monkey-freecodecamp算法题目

    Chunky Monkey(猴子吃香蕉, 分割数组) 要求 把一个数组arr按照指定的数组大小size分割成若干个数组块. 思路 利用size值和while语句确定切割数组的次数(定义temp将siz ...

  5. Leetcode 20 有效的括号valid-parentheses(栈)

    给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合. 左括号必须以正确的顺序闭合. 注意空字符串可被认 ...

  6. loj6485 LJJ 学二项式定理

    题目描述: loj 题解: 单位根反演. $[n|x]=\frac{1}{n} \sum _{i=0}^{n-1} (ω_n^x)^i$ 证明?显然啊,要么停在$(1,0)$要么转一圈. 所以说题目要 ...

  7. Linux菜鸟起飞之路【十】进程管理

    一.基本概念 进程:程序的一次动态执行 守护进程:在后台运行并提供系统服务的进程 僵尸进程:完成了生命周期但却依然留在进程表中的进程,我们称之为 “僵尸进程” 父进程:指已创建一个或多个子进程的进程. ...

  8. 【java】类成员的访问限制关系

  9. 【 android】When an app is installed on the external storage

    When an app is installed on the external storage: The .apk file is saved to the external storage, bu ...

  10. java 的多态(2013-10-11-163 写的日志迁移

    java 的多态性:(所谓多态--就是指一个引用(类型)在不同情况下的多种状态)   1.方法的多态:    重载(overload)   重写(覆盖 override)   2.对象的多态性:(本人 ...