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. Spark学习之数据读取与保存(4)

    Spark学习之数据读取与保存(4) 1. 文件格式 Spark对很多种文件格式的读取和保存方式都很简单. 如文本文件的非结构化的文件,如JSON的半结构化文件,如SequenceFile结构化文件. ...

  2. C++(extern关键字的理解和作用深入)

    extern关键字的理解和作用深入 extern是一个关键字,它告诉编译器存在着一个变量或者一个函数,如果在当前编译语句的前面中没有找到相应的变量或者函数, 也会在当前文件的后面或者其它文件中定义 引 ...

  3. Linux 学习(二)

    Linux相关命令 命令 说明 startx 当前用户界面切换至图形界面 init5 切换至另一用户的图形化界面 init3 从图形界面切换回文本界面 pwd 显示当前用户路径 logout 注销 s ...

  4. 左耳听风 ARTS Week 001

    要求:1.每周至少做一个 leetcode 的算法题 2.阅读并点评至少一篇英文技术文章 3.学习至少一个技术技巧 4.分享一篇有观点和思考的技术文章 1.每周至少做一个 leetcode 的算法题 ...

  5. 如何在Win8.1和Win2012上运用PowerShell快速生成、安装、导出自签名证书 (Self-Signed Certificate)

    自签名证书用途很广,测试,开发,本地或者云端网站(比如Microsoft Azure Web Site)都会使用到.本文会介绍一种在Win8.1和Win2012 R2上使用PowerShell快速生成 ...

  6. (转)Eclipse在线配置Hibernate Tools

    http://blog.csdn.net/yerenyuan_pku/article/details/52733403 查看Eclipse版本 Eclipse针对程序开发有很多发行版本,除了开发语言的 ...

  7. c++类简介

    C++类(Class)总结   一.C++类的定义     C++中使用关键字 class 来定义类, 其基本形式如下:class 类名{ public: //行为或属性  protected: // ...

  8. 梦想MxWeb3D协同设计平台 2018.10.12更新

    SDK开发包下载地址: http://www.mxdraw.com/ndetail_10107.html 1. 全新的在线的三维协同设计平台,高效异步方式,基于JavaScript和WebGL技术,前 ...

  9. js实现字符串反转

    方案1: var str = "abcdef"; console.log( str.split("").reverse().join("") ...

  10. 01Microsoft SQL Server

    Microsoft SQL Server Microsoft SQL Server 是Microsoft 公司推出的关系型数据库管理系统.具有使用方便可伸缩性好与相关软件集成程度高等优点,可跨越膝上型 ...