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. [转] Redis在windows下安装过程

    转载自(http://www.cnblogs.com/M-LittleBird/p/5902850.html) 一.下载windows版本的Redis 去官网找了很久,发现原来在官网上可以下载的win ...

  2. 鼠标拖拽移动Java界面组件

    默认的,Frame或者JFrame自身已经实现了鼠标拖拽标题栏移动窗口的功能. 只是,当你不满意java的JFrame样式,隐藏了标题栏和边框,又或者干脆直接使用JWindow,那你又该怎么实现鼠标拖 ...

  3. JVM GC调优一则–增大Eden Space提高性能

    缘起 线上有Tomcat升级到7.0.52版,然后有应用的JVM FullGC变频繁,在高峰期socket连接数,Cpu使用率都暴增. 思路 思路是Tomcat本身的代码应该是没有问题的,有问题的可能 ...

  4. Tcl之Read files for synthesis

    The following file is to read all design files into syntehsis tool automatically, like Cadence RTL C ...

  5. 三维重建:GitHub百度Apollo 2.0

    GitHub:https://github.com/ApolloAuto/apollo 1. 关于Apollo的数据:Apollo的数据会如何开放? 自动驾驶数据将包括具有高分辨率图像和像素级别标注的 ...

  6. ASP MVC

    V-view 显示层 C-controller 控制层 M-model 模型 D-database 数据库 S-Service 服务 D-Database/Dao 数据库/访问数据库的方法 View即 ...

  7. 部署bugzilla(bugzilla+apache+mysql+linux)

    工作原因,需要部署bugzilla.在此,容我新造个轮子.官方轮子:https://bugzilla.readthedocs.org/en/latest/installing/quick-start. ...

  8. 【CImg】基本像素操作

    继openCV之后接触的又一个C++视觉库——短小精干的CImg 刚开始接触的时候真的是..几乎无从下手,网上资料比较少,但发现有一篇非常有用的中文手册:http://wenku.baidu.com/ ...

  9. iOS,Core Animation--负责视图的复合功能

    简介 UIKit API UIKit是一组Objective-C API,为线条图形.Quartz图像和颜色操作提供Objective-C 封装,并提供2D绘制.图像处理及用户接口级别的动画.    ...

  10. java的标识符和关键词

    1.1.1 标识符   可以简单的理解为一个名字.在Java中,我们需要标识代码的很多元素,包括类名.方法.字段.变量.包名等.我们选择的名称就称为标识符,并且遵循以下规则: 标识符可以由字母.数字. ...