4.Spring4.x学习[核心篇][IOC/DI简介以及Spring中IOC的方式介绍]

来源:互联网 发布:蒙泰5.0软件官方下载 编辑:程序博客网 时间:2024/05/22 03:08
  • IOC概述
    IOC 是Inverse of Control(控制反转)的缩写,反转的是对象的控制权(new)。最初学习java的时候,我们都是在一个对象中通过new的方式,来创建一个对象。例如如下场景:演员获得电影信息
public class Actor {    public void action(){        Movie movie = new Movie();        movie.getMovieInfo();    }}
public class Movie {    public void getMovieInfo(){        System.out.println("movie name is ...,dirctoried by ...");    }}

以往的做法,如果我们Actor 要操作Movie的方法,那么必须在Actor 中new一个Movie的对象。
通过IOC的话,我们要如何实现呢?我们可以借助导演的角色,作为第三方的代理控制者。场景依旧如下:导演通知演员电影信息

public class Director {    //控制Actor    Actor actor = new Actor();    //控制Movie    Movie movie = new Movie();    public void informActor(){        actor.setMovie(movie);        actor.action();    }}
public class Actor {    //Movie作为Actor的成员,由Director分配    Movie movie;    public void action(){        movie.getMovieInfo();    }    //注入Movie属性    public void setMovie(Movie movie){        this.movie = movie;    }}
public class Movie {    public void getMovieInfo(){        System.out.println("movie name is ...,dirctoried by ...");    }}

通过Dircetor的角色,把Actor的Movie控制权反转到了Dircetor上面,Actor不需要自己new一个Movie,而是把Movie作为一个自身的成员,由Director通过set访问点把new好的Movie传入。这样就达到了释放控制权,解耦关系的作用。Director就相当于一个大管家,Actor需要的,Director会主动分配给Actor,这个就是控制反转的精髓所在。而在Spring中,Spring容器正是通过这种大管家的身份,给每个Bean分配他们所需要的资源的。

所以,IOC其实是一种思想,通过转交控制权托管给第三方,来简化自身的操作。而Spring把资源分配权转交给容器,然后每个角色只关注自己的action。所以Spring的核心是IOC,Spring中核心的角色是BeanFactory(Context)。

上面加粗的部分,其实说明了在Spring中IOC的一种方式,通过setter来进行属性注入。因为IOC的概念有些难理解,所以泰斗级的人物Martin Fowler提出了DI(Dependency Injection)依赖注入的概念来代替IOC,让调用者对某一接口的实现依赖关系由第三方注入,以移除调用类对某一接口的依赖。那么当然,依赖的接口,这时候也会作为一个属性被注入到调用类中。
既然Spring中有了DI的概念,就知道了,需要注入的是属性,那么被调用类也就成为了Bean,Bean中有属性,有构造法方法,所以,每个Spring容器管理的对象,都可以作为Bean来对待。DI的思想,成了Spring IOC的核心,而Bean,无疑是Spring中最重要的角色了。
那么下面,也就不难理解Spring会有下面几种IOC的实现方式了。

  • Spring的IOC实现方式
    1.构造函数注入
    2.属性注入(setter注入)
    3.接口注入(工厂方法)

    1. 构造参数注入:通过调用类的构造方法,把属性通过构造函数变量传入
public class MoAttack{    private GeLi geli;    public MoAttack(GeLi geli) {        this.geli = geli;           }    public void cityGateAsk() {        geli.responseAsk("墨者革离");    }}
public interface GeLi {    void responseAsk(String saying);}
public class Director {   public void direct(){       GeLi geli = (GeLi) new LiuDeHua();       MoAttack moAttack = new MoAttack(geli);       moAttack.cityGateAsk();   }}
  1. 属性注入:通过setter方式把属性注入
public class MoAttack {    private GeLi geli;    public void setGeli(GeLi geli) {        this.geli = geli;           }    public void cityGateAsk() {        geli.responseAsk("墨者革离");    }}
public interface GeLi {    void responseAsk(String saying);}
public class Director {   public void direct(){       GeLi geli = (GeLi) new LiuDeHua();       MoAttack moAttack = new MoAttack();       moAttack.setGeli(geli);       moAttack.cityGateAsk();   }}
  1. 接口注入
public class MoAttack implements ActorArrangable {    private GeLi geli;    //实现接口方法    public void injectGeli(GeLi geli) {        this.geli = geli;           }    public void cityGateAsk() {        geli.responseAsk("墨者革离");    }}
public interface ActorArrangable {   void injectGeli(GeLi geli);}
public interface GeLi {    void responseAsk(String saying);}
public class Director {   public void direct(){       GeLi geli = new LiuDeHua();       MoAttack moAttack = new MoAttack();       moAttack.injectGeli(geli);       moAttack.cityGateAsk();   }}

以上大致浏览下各种注入方式,进一步说民,DI或者是IOC只是一种思想。通过不同的方式,可以达到同一个效果。但是有个问题,我们虽然对MoAttack 进行了注入,但是是通过Director实例进行的。如果我现在想换个导演,让导演,剧本,和演员都解耦,我是不是还得再找一个托管的类?在Spring中,早已经把所有的注入类看做是一个Bean,Spring通过容器作为其他所有Bean的大管家,对其他Bean进行依赖注入。只需要通过简单的xml配置或者是注解配置,就可以建立Bean之间的关系。通过new XmlBeanFactory(“beans.xml”)或者是new ApplicationContext(“beans.xml”)等方式,即可启动Spring容器,容器会返回就绪的Bean。
那么Spring又是通过什么方式来进行DI的呢?这个就要归功于Java的反射,反射则是Spring IOC的核心。
以上就是IOC和SpringIOC的简介部分,至于Spring是用什么方式,以及Spring中如何通过IOC装配Bean,后面会有详解。

原创粉丝点击