Spring-01-IOC控制反转/DI依赖注入

来源:互联网 发布:微博域名格式 编辑:程序博客网 时间:2024/06/16 22:55

一.Spring简介

Spring是一个开放源代码的设计层面框架,解决业务逻辑层和其他各层的耦合问题,它将面向接口的编程思想贯穿整个系统应用。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架
Spring框架主页
Spring框架下载地址

二.Spring模块

Spring共有6大模块,如下图所示,下图显示的6大模块表达了Spring的功能,使用者可以有选择的使用不同的模块来帮助自己完成项目

这里写图片描述

Core

即Spring容器,Spring容器的主要特性是IOC,故Spring容器又被称为IOC容器,其主要功能是通过Spring容器管理类的依赖以实现程序的解耦合

AOP

采用了面向切面编程来实现很多基础功能的解耦,比如:事务管理、日志、权限验证

DAO

提供了对数据库JDBC的封装,使用模板类来简化数据操作,同时还提供了声明式事务处理等功能

ORM

提供了对主流的对象关系映射框架Hibernate,Mybatis的支持

JEE

对Java企业级开发提供了一些解决方案,例如EJB、JMS等

WEB

提供了自己的MVC框架SpringMVC和对显示层框架的集合支持

三.IOC

IOC全称为Inversion of Control,译为控制反转,是Spring框架的重要特征,即通过Spring容器进行依赖对象的创建及维护,它包括依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)
IOC并非面向对象编程的专用术语,而是用来描述Java框架的特性。IOC可以认为是一种全新的设计模式,但是理论和时间成熟相对较晚,所以并没有包含在主流的设计模式的定义中

3.1 IOC形成的原因:

1) IOC的由来—–耦合关系

Java中经常会用到接口驱动,接口驱动有很多好处,可以提供不同灵活的子类实现,增加代码稳定和健壮性等等,但是接口一定是需要实现的,创建对象时需要指明确定的对象,于是接口和对象的耦合关系就产生了,如:

public class GermanyCar{     private Car bmw =new BMW();     public void CarName() {          System.out.println(bmw.getName());    }}

类GermanyCar与类BMW产生了依赖关系(耦合),如果想使用Car接口的另外一个实现就需要更改代码了。

2) 优化—–使用工厂类

可以建立一个Factory(工厂类)来根据条件生成想要的Car接口的具体实现,即:

Interface CarFactory{   Car createCar(Object condition){      if(condition == con_1){          return new BMW();      }      else if(condition == con_2){          return new BENZ();      }      else{          return new VM();      }    }}

创建工厂类看似解决了耦合的问题,当使用不同的Car对象的实现类时,只需要更改CarFactory工厂类的createCar方法的条件,但实质上这种代码耦合并没有完全解决,因为使用时还是要创建工厂类,

public class GermanyCar{     CarFactory factory = new CarFactory();     Car bmw = factory.createCar(con_1);     public void CarName() {          System.out.println(bmw.getName());    }}

通过IOC可以彻底解决这种耦合,它把耦合从代码中移出去,放到统一的XML 文件中,通过一个容器在需要的时候把这个依赖关系形成,即把需要的接口实现注入到需要它的类中,即依赖注入(DI)

3) 依赖注入(DI)

依赖注入的思想是:当一个类(GermanyCar)对另一个类(BMW)有依赖时,不再该类(GermanyCar)内部对依赖的类(BMW)进行实例化,而是之前配置一个beans.xml,告诉容器所依赖的类(BMW),在实例化该类(GermanyCar)时,容器自动注入一个所依赖的类(BMW)的实例。

public Interface Car{    public String getName();}//使用IOC容器后,GermanyCar不用再创建对象的实现类,实现类通过注入DI的方式由IOC进行管理public class GermanyCar{    private Car car;    public String getName(){        return this.car.getName();    }    public void setCar(Car car){        this.car = car;    }}

在xml文件中配置依赖关系

<bean id="GermanyCar" class="GermanyCar">    <!--配置文件中设置依赖关系-->    <property name="Car" ref="BMW"/></bean><bean id="BMW" class="BMW"/>

这样,GermanyCar类在调用方法getName( )的时候,并不知道BMW类的存在,它只知道调用一个接口Car,而Car的具体实现是通过BMW类完成,并在使用时由容器自动注入,这样大大降低了不同类间相互依赖的关系。

4) 总结:

IOC用来描述Spring容器的特性—–通过DI(依赖注入)和DL(依赖查找)进行依赖对象的创建及维护,具有IOC特性的Spring容器实现了Java代码的解耦合,大大的提高了大型项目的灵活性和可维护性。
DI是Spring容器实现其功能(创建及维护依赖对象)的方法

四.DI

依赖注入,通过IOC容器进行依赖关系的建立,DI的实现方式共有3种:1,setter方法注入 2,构造方法注入 3,接口注入

1)setter方法注入

业务类:

public class GermanyCar{    private Car car;    //setter方法    public void setCar(Car car){        this.car = car;    }    //业务代码    ......}

xml文件:

<bean id="GermanyCar" class="GermanyCar">    <property name="Car" ref="BMW"/></bean><bean id="BMW" class="BMW"/>

2)构造方法注入

业务类:

public class GermanyCar{    private Car car;    //构造方法    public GermanyCar(Car car){        this.car = car;    }    //业务代码    ......}

xml文件:
使用<constructor-arg/>标签进行配置,index属性用来设置构造方法中参数的顺序,如果有多个参数,则按照index设置的顺序,从0,1,2….依次进行配置

<bean id="GermanyCar" class="GermanyCar">    <constructor-arg index="0" ref="BMW"/></bean><bean id="BMW" class="BMW"/>

3)接口注入

局限性比较大,很少用
业务类:

public class GermanyCar{    //使用接口及反射常见对象    private Car car = Class.forName("BMW");    //业务代码    ......}

xml文件:
使用<constructor-arg/>标签进行配置,index属性用来设置构造方法中参数的顺序,如果有多个参数,则按照index设置的顺序,从0,1,2….依次进行配置

<bean id="GermanyCar" class="GermanyCar"/><bean id="BMW" class="BMW"/>