spring笔记(2)——spring核心控制反转IoC详解及入门示例

控制反转,一开始理解起来真的就完全不懂在说什么,看了几遍以后,粗浅的说说自己的理解。

在传统的java程序开发中,当我们需要一个对象时,都是在程序内部主动的去创建一个对象,而这样的做法会使得程序很复杂,,需要去掌握new这个对象的全部过程;而控制反转的思想就是,当我需要一个对象的时候,我不再在程序内部自己去创建了,而是告诉一个第三方,我需要一个什么样的对象,然后这个第三方就会主动的把我们所需要的这个对象送到程序中,这样我就不用去知道这个对象是如何创建的。

想到一个生活中的例子,觉得比较能够描述这个控制反转的过程,将就着理解一下。

以前,外卖没有兴起的时候,我们想要吃鸡排,常规的途径就是我们去买鸡排、油、盐、辣椒等,然后回来自己准备锅和灶,在然后就是自己去炸鸡排了。在这个过程中,我们需要自己去学会从买鸡排和炸鸡排的全部流程。现在,有了美团外卖和正新鸡排店,我们想要吃鸡排了,最简单的方法就是,我打开美团外卖,找到正新鸡排,告诉他我想要吃一份微辣的鸡排,然后把电话和联系方式留下,自然会有人把鸡排送上门。在这个过程中,我们不需要去了解,一份鸡排是如何制作出来的,但是我们最后得到我们想要的正新鸡排。

这里,美团外卖就充当了上面描述中的第三方这个角色,我们告诉这个第三方,我想要一块微辣的正新鸡排,这个正新鸡排就是我们想要的对象。

好了回到我们程序中来,说一下控制反转的概念:控制反转是一种描述(在java中可以是XML或者注解),并通过第三方去产生或获取特定对象的方式。

在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入,其最大的好处在于降低对象之间的耦合度,在一个系统中,有些类,我们不需要知道他是如何实现的,只需要知道它有什么用就可以了。这里对象的产生依赖于IoC容器,而不是开发者主动的行为。

接下来,用书上的一个例子来完成Spring IoC实现的一个入门实例。

问题的背景是我想要喝一杯果汁,但是我不想自己去买水果和果汁机,然后我在自己去用果汁机榨一杯果汁,这个过程太复杂了,现在我们通过控制反转的理念来完成这一个过程,我们只需提出我们的需求Source,然后油果汁制造器JuiceMaker2去完成这个果汁的生产,我再直接去获取这个果汁就行了,我们并不去参与生产果汁的这个过程。

首先有一个果汁制造器类JuiceMaker2

public class JuiceMaker2 {
    private String beverageShop;
    private Source source;

    public String getBeverageShop() {
        return beverageShop;
    }

    public void setBeverageShop(String beverageShop) {
        this.beverageShop = beverageShop;
    }

    public Source getSource() {
        return source;
    }

    public void setSource(Source source) {
        this.source = source;
    }

    public String MakeJuice(){
        String juice="这是一杯由"+beverageShop+"饮品店,提供的"+source.getSize()
                +source.getSugar()+source.getFruit();
        return juice;
    }
}

然后有一个描述果汁类型的清单Source类

public class Source {
    private String fruit;
    private String sugar;
    private String size;

    public String getFruit() {
        return fruit;
    }

    public void setFruit(String fruit) {
        this.fruit = fruit;
    }

    public String getSugar() {
        return sugar;
    }

    public void setSugar(String sugar) {
        this.sugar = sugar;
    }

    public String getSize() {
        return size;
    }

    public void setSize(String size) {
        this.size = size;
    }
}

然后我们去XML文件中去描述这个清单文件

 <bean id="source" class="com.learn.ssm.chapter9.pojo.Source">
        <property name="fruit" value="橙汁"/>
        <property name="sugar" value="少糖"/>
        <property name="size" value="大杯"/>
 </bean>

同时对果汁制造器也进行描述

<bean id="juiceMaker2" class="com.learn.ssm.chapter9.pojo.JuiceMaker2">
        <property name="beverageShop" value="贡茶"/>
        <property name="source" ref="source"/>
</bean>

完整配置文件如下:

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


    <!-- id:该实例的名称,class:该实例的类型,是一个完整类名路径,包括包名 -->
    <!-- property:该实例的属性名称,value:属性值 -->

    <bean id="beanPostProcessor" class="com.learn.ssm.chapter9.bean.BeanPostProcessorImpl"/>

    <bean id="source" class="com.learn.ssm.chapter9.pojo.Source">
        <property name="fruit" value="橙汁"/>
        <property name="sugar" value="少糖"/>
        <property name="size" value="大杯"/>
    </bean>


    <bean id="juiceMaker2" class="com.learn.ssm.chapter9.pojo.JuiceMaker2">
        <property name="beverageShop" value="贡茶"/>
        <property name="source" ref="source"/>
    </bean>
</beans>

接下来我们就可以通过IoC容器去获取这些对象了。

public class Test {

    public static void main(String[] args) {
        //这里先不详细解释代码,后面再分析,先了解一下
        
        ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");

        //通过配置文件中的id名,来获取一个JuiceMaker2对象。
        JuiceMaker2 juiceMaker2=(JuiceMaker2)ctx.getBean("juiceMaker2");

        //调用JuiceMaker2的方法
        String juice=juiceMaker2.MakeJuice();
        System.out.println(juice);
        ctx.close();
    }
}

通过上面的实例,我们已经获取了一个JuiceMaker2对象,但是这个对象的实例化并不是由我们自己去完成的,我们只是在XML文件中,描述了我们想要的东西,实例化的过程是有IoC容器来完成了的,这样就很好减轻了系统的耦合度,比如果汁店改进了果汁生产的流程,这些我们都不用去理会,因为我们并不参与果汁的生产过程,这样我们获取果汁的这段代码,也完全不需要改变。

spring笔记(2)——spring核心控制反转IoC详解及入门示例

这里看一个整个项目的工程结构,如果不知道怎么搭建开发环境,可以去看我的上一篇博客《Spring笔记(1)——开发环境的搭建》

spring笔记(2)——spring核心控制反转IoC详解及入门示例

以上是我个人的一些理解,若有错误,欢迎再评论中指出,共同进步。