控制反转——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. 一点对原生HTTP请求的理解与总结

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10946165.html,多谢,=.=~ 术语 HTTP:超文本传输协议,规定Web浏览器如何从W ...

  2. python基础教程总结4—基本语句

    一.print 和 import 的更多信息 print 打印多个表达式也是可行的,只要将它们用逗号隔开就好: >>> print('Age:' , 42) Age: 42 可以看到 ...

  3. UVA 10537 Toll! Revisited (逆推,最短路)

    从终点逆推,d[u]表示进入u以后剩下的货物,那么进入u之前的货物数量设为y,d[u] = x,那么y-x=ceil(y/20.0)=(y-1)/20+1=(y+19)/20. (y-x)*20+r= ...

  4. MFC:DISP_FUNCTION 参数

    /*#include <afxdisp.h>DISP_FUNCTION( theClass, pszName, pfnMember, vtRetVal, vtsParams )参数:the ...

  5. samba修改smb.conf后,不需要重启服务,就可生效

    在修改完smb.conf后,不需要重启服务.在Centos7.3与Ubuntu18.04上验证都没有问题. 猜测可能的原因:samba是在客户端进行连接时,smb服务程序读取smb.conf配置文件信 ...

  6. 动态代理--Cglib

    JDK 的Proxy 实现,需要代理对象实现接口: package com.utils; import java.lang.reflect.InvocationHandler; import java ...

  7. servlet实现简单的反向代理

    项目基于Spring 须要的依赖为: <dependency> <groupId>org.mitre.dsmiley.httpproxy</groupId> < ...

  8. cocos2dx for lua 摄像机移动

    在cocos2dx中,我们想通过移动摄像机来做一些特殊处理,比如将摄像机聚焦在某个物体上,或者摄像机颤抖,摄像机原理观察sprite回收状况等等, 都需要通过相机移动来使用. cocos2dx中的摄像 ...

  9. 简单的C++ DLL注入

    今天呢,我们来讨论一下用C++实现DLL注入的简单方法. 环境: Visual Studio 2015及以上 Windows 7及以上 入门需要了解的: DLL是什么:DLL_360百科 DLL是Dy ...

  10. Service Mesh是什么技术

    https://blog.csdn.net/weixin_38044696/article/details/80257488 Service Mesh是什么技术 2018年05月09日 22:07:4 ...