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. 个人作业-Alpha测试

    课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/ 作业要求 https://edu.cnblogs.com/campu ...

  2. Reuse a SSL socket

    It's possible to reuse a SSL socket after proper cleanup. See SSL Socket free and shutdown on stacko ...

  3. 梦想CAD控件网页版关于自定义命令

    在CAD控件操作中,为方便使用者,使用自定义命令发出命令,完成CAD绘图,修改,保存等操作.点击此处在线演示. _DMxDrawX::RegistUserCustomCommand 向CAD控件注册一 ...

  4. IDEA中springboot项目打包成jar

      springboot的打包方式有很多种.有打成war的,有打成jar的,也有直接提交到github,通过jekins进行打包部署的.这里主要介绍如何打成jar进行部署.不推荐用war,因为spri ...

  5. 07Oracle Database 数据表

    Oracle Database 数据表 DDL 数据定义语言 -  建立数据库对象 create /alter/ drop/ truncate 创建表 Create table table_name( ...

  6. 数据库——DBUtils和连接池

    第一章 DBUtils如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils.DBUtils就是JDBC的简 ...

  7. A5. JVM 如何判断GC对象

    [概述] 在堆里面存放着 Java 世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还 “存活” 着,哪些已经 “死去”(即不可能再被任何途径使用的对象). ...

  8. angular4打包以后,刷新报404

    项目打包以后,上传到服务器,可以正常的切换页面,但是一旦刷新就会报404,找不到页面,其解决方法是:在app.module.ts里面引入下面的模块: import {HashLocationStrat ...

  9. 一步一步实现基于GPU的pathtracer(三):path tracing 简述

    全局光照这个名词在计算机图形学里已经不算一个新名词了,现在一提到拟真度,很多人基本上都会去想到全局光照,这个名词上世纪七八十年代就有了,好像是由一个叫Jim Kajiya的大神在他那篇已经被引用了不知 ...

  10. 利用CMD 創建新文件的機種方法

    用 CMD 創建新文件 説明一下: 是在Windows的 CMD命令行模式下,或者在PowerShell命令行模式下創建新文件的機種方法. 創建空文件 cd.>a.txt cd.表示改变当前目录 ...