IOC(Inversion of Control):控制反转

以下以课程与老师的安排来介绍控制反转。

一个合理的课程编排系统应该围绕培训的内容为核心,而不应该以具体的培训老师为核心,这样才能在正常授课时可以随意选取合适的老师来上课,而非绑定到一个老师身上。

一、探索IOC

  1、最紧耦合度的编法

public class JavaTrad {
public void JavaCourse(){
Bill bill=new Bill();//引入讲师,使讲师直接侵入培训
bill.teach("Spring IoC章节!"); }
}
public class Bill {
public void teach(String saying){
System.out.println(saying);
}
}

老师和课程一一对应,完全耦合,无法做到将代码重心放到课程内容上,而且每次修改讲师后,需要修改源码。

  2、较紧耦合度接口式编法

public interface Teacher  {
public void teach(String saying);
}
public class Bill implements Teacher{
@Override
public void teach(String saying){
System.out.println(saying);
}
}
public class JavaTrad {
public void JavaCourse(){
Teacher teacher=new Bill();//引入教师接口
teacher.teach("Spring IoC章节!");//通过接口进行授课
}
}

Bill讲师实现Teacher接口,利用多态特性,在课程类中让Bill讲师实现Teacher接口。但是这样的话课程类就得和Teacher接口、Bill讲师类都关联,并没有达到我们所期望的授课内容仅依赖与课程类的目的。

所以我们仍然需要找到一个方法来松耦合。

  3、引入中介类chairman来松耦合

public interface Teacher  {
public void teach(String saying);
}
public class Bill implements Teacher{
public void teach(String saying){
System.out.println(saying);
}
}
public class JavaTrad{
private Teacher teacher; public void javaCourse(){
teacher.teach("Spring IoC章节!");
} public void injectTeacher(Teacher teacher) {//聚合
// TODO Auto-generated method stub
this.teacher=teacher; }
}
public class Chairman {
public void managerCourse(){
Teacher teacher=new Bill();
JavaTrad javatrad=new JavaTrad();
javatrad.injectTeacher(teacher);
javatrad.javaCourse(); }
public static void main(String[] args) {
new Chairman().managerCourse();
} }

课程类中只需要引入一个实现老师接口的对象即可,具体是哪个对象实现了老师接口,课程类不用管,这个工作交给了chairman类来分配,解决了具体讲师类和课程类之间的紧耦合关系,但是每次换讲师之前还得修改chairman代码,所以还可以有所改进。

二、IoC概念

  在实际应用开发中,需要尽量避免和降低对象之间的依赖关系,即降低耦合,一般的业务对象之间,业务对象与持久层之间都存在这样或那样的依赖关系。那么,如何降低对象之间的依赖关系,IoC正式解决这个问题。

  在传统的实现中,由程序内部的代码来控制对象之间的关系。当一个对象需要依赖另一个对象时,我们用new来创建它的依赖对象,实现两个组件的组合关系。这种实现方式会造成组件之间的耦合。控制反转是指应用程序中对象的创建、销毁等不再由程序本身编码实现,而是由外部的Spring容器来控制,所以称为控制反转。这种控制权的转移带来的好处是降低了对象简单间的依赖关系,即实现了解耦。

  IoC的字面意思是控制反转,它包括两个内容:其一就是控制,其二就是反转。控制就选择被调用者类的控制权,反转指这种控制权从具体的调用者类中移除,转而交给一个装配者手中了。

  在软件模式中具体表现为:某一个接口具体实现类的选择控制权从调用者类中移除,转交给第三方仲裁。第三方为配置文件,由IOC容器装载配置文件之后,自动映射生成对象及其属性。

  IoC的具体方法是依赖注入DI(Dependency ):组件之间的依赖关系由容器在运行期间决定,形象的说,即由容器动态的将某种依赖关系注入到主键之中。

三、依赖注入DI的三种方式

  1、构造函数注入

    在构造器注入中,我们通过在调用者类的构造器中将被调用者对象变量赋值即可完成注入

public class Chairman {
public void managerCourse(){
Teacher teacher=new Bill();
JavaTrad javatrad=new JavaTrad(teacher); //构造器注入
javatrad.javaCourse();
}
public static void main(String[] args) {
new Chairman().managerCourse();
} }
public class JavaTrad  {
private Teacher teacher; public JavaTrad(Teacher teacher){//构造函数注入方法
this.teacher=teacher;
}
public void javaCourse(){
this.teacher.teach("Spring IoC章节!");
}
}

  2、set属性注入方式

    在set属性注入中,我们通过使用调用者的set方法将teacher的具体对象传入teacher中,即可完成注入。 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean name="teacher" class="com.weikun.IoC6.Bill"></bean>
<bean id="trad" class="com.weikun.IoC6.JavaTrad">
<property name="teacher" ref="teacher"></property>
</bean>
</beans>
public class JavaTrad{
private Teacher teacher; public Teacher getTeacher() {
return teacher;
} public void setTeacher(Teacher teacher) {
this.teacher = teacher;
} public void JavaCourse(){
this.teacher.teach("Spring IoC章节!");
}
}
public class Test {
public static void main(String[] args) {
Resource resource=new ClassPathResource("applicationContext1.xml");//容器
BeanFactory beanFactory=new XmlBeanFactory(resource);
JavaTrad javaTrad=(JavaTrad)beanFactory.getBean("trad");
     Teacher teacher=(Teacher)beanFactory.getBean("teacher");
javaTrad.getTeacher().teach("asd");
}
}

  3、接口注入方式

    让调用者也实现一个接口,接口中定义一个接口注入方法,在具体调用者类中实现它,从而完成属性的注入(方法类似于自定义一个setter方法)

public class JavaTrad  implements Trad{
private Teacher teacher; public void JavaCourse(){
this.teacher.teach("Spring IoC章节!");
}
public void injectTeacher(Teacher teacher) {//接口属性注入方式
// TODO Auto-generated method stub
this.teacher=teacher;
}
}

public interface Trad {
void injectTeacher(Teacher teacher);
}

  

  4、四种依赖注入方式的对比

    1)、接口注入

      从注入方式的使用上来说,接口注入是不提倡的一种方式,极少被用户使用。因为它强制被注入对象实现容器的接口,带有“侵入性”,而构造方法注入和setter方法注入则不需要如此。

    2)、setter注入

      这种注入方式与传统的JavaBean写法很相似,程序员更容易理解和接受,通过setter方式设定依赖关系显得更加直观自然。

      缺点是组件使用者或许会忘记组件注入需要的依赖关系,同时依赖可能会因为setter方法的调用而被修改。

    3)、构造注入

      这种方法的优点是:构造注入可以在构造器中决定依赖关系的注入顺序。依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明。

      缺点:对于复杂的依赖关系如果采用构造注入,会导致构造器过于臃肿,难以阅读。

  

  5、IoC的装载机制

    1、IoC容器

      Spring提供了强大的IoC容器来管理组成应用程序中的Bean,要利用容器提供的服务,就必须配置Bean,配置文件描述了Bean的定义和他们之间的依赖关系。Spring通过大量引入了Java的反射机制动态生成Bean对象并注入到程序中避免硬编码,实现了该功能的核心组件是BeanFactory,而ApplicationContext继承了BeanFactory接口,提供了更多的高级特性,建议优先使用后者。

      ApplicationContext的实现类如下:

      1)、ClassPathXmlApplicationContext:从CLASSPATH下加载文件

      2)、FileSystemXmlApplicationContext:从文件系统中加载文件  

    首先,可以通过任一实现类来将配置文件中定义的Bean加载到容器中,如:(这里的ctx就是容器)

      1)、ApplicationContext ctx=new ClassPathXmlApplicationContext("bean.xml");

       2)、ApplicationContext ctx=new FileSystemXmlApplicationContext("classpath:bean.xml");

    然后,通过下列语句获取Bean的实例

      Moveable animal=(Moveable) ctx.getBean("animal");

  

  6、IoC的零配置注解写法

    如果Bean不是自己编写的类(如SessionFactory),注解配置将无法实施,此时XML配置是唯一可以使用的方式

    1)、@Autowired

        它对类的成员变量、方法以及构造方法进行标注,完成自动装配的工作。

        

import org.springframework.beans.factory.annotation.Autowired;
public class Animal{
  Private MessagePriter printer;
@Autowired
public void setPrinter(MessagePriter printer){
this.priter=printer;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
">
<bean id="movePrinter" class="com.zxc.A.movePriter"></bean>
<bean id="animal" class="com.zxc.A.JavaTrade">
<property name="animalType" value="Bird"/>
<property name="moveMode" value="fly"/>
</bean>
</beans>

    2)、@Qualifier  

        如果一个bean的属性可能来自多个其他的候选bean,导致Spring无法确定使用那一个bean,当Spring容器在启动时就会抛出BeanCreationException异常。Spring允许我们通过@Qualifie注解指定注入bean的名称。

import org.springframework.beans.factory.annotation.Autowired;
public class Animal{
@Autowired
  Private @Qualifier(value="screen")MessagePriter printer;
}

        通常@Qualifer和@Autowired结合使用,且置于成员变量类型的前面。

    3)、@Resource

        @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入的,而@Resource默认按byName自动注入罢了。

    4)、@Component

        虽然可以通过@Autowired或@Resource在Bean类中使用自动注入功能,但是还是需要在XML中定义<bean>。而通过注解的@Component就可以通过注解就定义Bean,在类前加上@Component

Sping框架的IOC特性的更多相关文章

  1. Sping框架的IOC特性 悲观锁、乐观锁 Spring的AOP特性

    Sping框架的IOC特性 IOC(Inversion of Control):控制反转 以下以课程与老师的安排来介绍控制反转. 一个合理的课程编排系统应该围绕培训的内容为核心,而不应该以具体的培训老 ...

  2. sping 框架学习之——初始篇

    sping框架学习: 1,什么是spring框架 spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以 ...

  3. Spring框架中IoC(控制反转)的原理(转)

    原文链接:Spring框架中IoC(控制反转)的原理 一.IoC的基础知识以及原理: 1.IoC理论的背景:在采用面向对象方法设计的软件系统中,底层实现都是由N个对象组成的,所有的对象通过彼此的合作, ...

  4. LCLFramework框架之IOC

    我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 借助于"第三方"实现具有依赖关系的对象之间的解 ...

  5. Spring框架(3)---IOC装配Bean(注解方式)

    IOC装配Bean(注解方式) 上面一遍文章讲了通过xml来装配Bean,那么这篇来讲注解方式来讲装配Bean对象 注解方式需要在原先的基础上重新配置环境: (1)Component标签举例 1:导入 ...

  6. Spring框架之IOC(控制反转)

    [TOC] 第一章Spring框架简介 IOC(控制反转)和AOP(面向方面编程)作为Spring框架的两个核心,很好地实现了解耦合.所以,简单来说,Spring是一个轻量级的控制反转(IoC)和面向 ...

  7. Spring框架的IOC核心功能快速入门

    2. 步骤一:下载Spring框架的开发包 * 官网:http://spring.io/ * 下载地址:http://repo.springsource.org/libs-release-local/ ...

  8. Atitit  hre框架v5 新特性  HREv5

    Atitit  hre框架v5 新特性  HREv5 1. V5新特性 apiurl2="/wrmiServlet";1 2. V1 新特性1 3. V2 新特性 添加php版1 ...

  9. (精简)Spring框架的IoC(替代工厂类实现方法)和AOP(定义规则,约定大于配置)

    Spring的核心框架主要包含两个技术,分别用来处理工厂类,以及事务处理和连接管理的. 两大核心概念 1)  IoC:控制反转,在现在的开发中,如果想建立对象并设置属性,是需要先new对象,再通过se ...

随机推荐

  1. 42使用NanoPiM1Plus在Android4.4.2下的录音测试

    42使用NanoPiM1Plus在Android4.4.2下的录音测试 大文实验室/大文哥壹捌陆捌零陆捌捌陆捌贰21504965 AT qq.com完成时间:2017/12/5 17:51版本:V1. ...

  2. python网络爬虫。第一次测试-有道翻译

    2018-03-0720:53:56 成功的效果如下 代码备份 # -*- coding: UTF-8 -*- from urllib import request from urllib impor ...

  3. 短URL生成

    算法原理 算法一 1)将长网址md5生成32位签名串,分为4段, 每段8个字节; 2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略 ...

  4. IE 浏览器在地址栏输入中文字符,发送get请求报400错误的问题

    因为学校有JavaWeb的课程,所以才接触这方面.最近遇到了个小问题. 先看一段很简单的jsp代码例子 <%@ page language="java" import=&qu ...

  5. vue学习图解

    vue2.0版本的学习图解个人心得!本文为原创禁止转载!!转载需要注明出处,谢谢合作!!!

  6. What is JSON

    JSON (JavaScript Object Notation)  是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON具有以下这些形式: 对象是一个无序的“‘名称/值’对” ...

  7. bootstrap datatable 数据刷新问题

    在项目中,页面初始化的时候,通过通过向后台请求数据,页面初始化完之后,datatable是有数据的,当我点击页面的搜索按钮(按照时间过滤数据),datatable的数据要能重新刷新或者重载:这一点,我 ...

  8. java虚拟机(八)--java性能监控与故障处理工具

    问题定位: 除了个人经验,知识,工具也是很重要的,通过数据进行问题分析,包括:运行日志.异常堆栈.GC日志.线程快照(threaddump/javacore文件 ).堆转储快照(heapdump/hp ...

  9. Linux下查看CPU信息、机器型号等硬件信息命令

    Linux下查看CPU信息.机器型号等硬件信息命令 编写一个bash脚本: vim info.sh #!/bin/bash cat /etc/issue echo "____________ ...

  10. JAVA基础——集合类汇总

    一.集合与数组 数组(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用. 集合(只能存储对象,对象类型可以不一样)的长度可变,可在多数情况下使用. ...