一个简单的案例帮你理解什么是SpringIOC(适合新手理解其思想)

java发展到这个阶段可以说Spring框架功不可没,这个是一个超牛的框架,即便是目前最火的Springboot也离不开Spring框架的支持,或者说是Spring框架的一个升级。这篇文章主要是对Spring框架的IOC思想进行一个讲解。帮大家体会这种思想的使用。也会通过一个使用案例来解释说明。

一、什么是IOC

IOC全名叫做控制反转。英文名是Inversion of control。有些时候也叫作依赖注入,其实这是俩不同的概念。有些时候把他们划等号是因为描述的是一个功能,从两个角度来分析。

既然名字叫做IOC我们来看看,控制什么,反转什么。

1、控制什么:控制对象的创建和销毁,指的是控制对象的生命周期。

2、反转什么:之前我们创建一个对象都是new,现在有了IOC了,指的是把对象的控制权交给了IOC容器。

这俩概念如果你还不理解,可以看下面一个简单的案例,来体会一下这个控制反转的思想。

假如说有一个用户,有一辆车,每天就干两件事,那就是上学和回家。

阶段一:用户自己创建一辆车完成功能

首先定义一辆车:

public class Benz{
    @Override
    public void start() {
        System.out.println("奔驰车启动了");
    }
    @Override
    public void turn() {
        System.out.println("奔驰车转弯了");
    }
    @Override
    public void stop() {
        System.out.println("奔驰车刹车了");
    }
}

然后用户是这样来实现:

public class User {
    private Benz car =  new Benz();
    public void goSchool(){
        car.start();
        car.turn();
        System.out.println("到达学校");
        car.stop();
    }
    public void goHome(){
        car.start();
        car.turn();
        System.out.println("到家了");
        car.stop();
    }
}

现在使用是用户自己创建一辆车完成上班下班的功能,肯定是不合理。因为用户只是想用一辆车来完成上班下班的功能,每次回家之前先造一辆车太麻烦了。怎么办呢?干脆用户需要车的时候,给他传过去一辆。

阶段二:给用户传递一辆奔驰车来完成功能

如果给用户传递呢?方法很简单,只需要在用户的构造方法上,加一个车的参数即可。

public class User {
    private Benz car;
    public User(Benz car) {
        this.car = car;
    }
    public void goSchool(){
        car.start();
        car.turn();
        System.out.println("到达学校");
        car.stop();
    }
    public void goHome(){
        car.start();
        car.turn();
        System.out.println("到家了");
        car.stop();
    }
}

现在貌似实现了我们的功能,用户需要一辆车的时候,只需要给他传递过去一辆车即可,没毛病吧,但是果断时间需求又变了,用户又买了一辆宝马,不想用奔驰了。于是我们手忙脚乱的改,把所有的奔驰类全换成宝马类,有过一段时间用户又买了一辆奥迪,又开始手忙脚乱的改,这也太麻烦了。干脆把所有的车换成一个接口。

阶段三:给用户传递一辆车完成功能(不是具体的车)

于是,我们先定义一个car接口,然后让奔驰宝马实现这个接口就好了。

public interface Car {
    public void start();
    public void turn();
    public void stop();
}
public class Benz  implements Car{
    @Override
    public void start() {
        System.out.println("奔驰车启动了");
    }
    @Override
    public void turn() {
        System.out.println("奔驰车转弯了");
    }
    @Override
    public void stop() {
        System.out.println("奔驰车刹车了");
    }
}
//宝马、奥迪一样

然后我们的用户类里面只需要给他传递一辆车,不指定是什么车。

public class User {
    private Car car;
    public User(Car car) {
        this.car = car;
    }
    public void goSchool(){
        car.start();
        car.turn();
        System.out.println("到达学校");
        car.stop();
    }
    public void goHome(){
        car.start();
        car.turn();
        System.out.println("到家了");
        car.stop();
    }
}

现在完事具备,好像已经很完美了,用户上学回家的过程,使用什么车,给他传递一辆就OK了,但是我们想过没有,谁给用户传递的,难道我们在测试的时候,自己写代码先new一辆嘛?用户第二天还想用宝马,难道我们再new一辆嘛?而且如果用户每天换一辆,而且有十几辆车,怎么办呢?假如又有一个新用户,也想实现上面的功能,这时候就需要想办法了。

干脆呀,把这些车全部放在一个容器内,需要的时候拿出来就好了,就不用我们自己创建一个给用户了。这样不管是谁想要车,什么时候想要车,需要的时候去这个容器内去拿就好了。这时候就是一个控制反转的思想,我们把车的创建销毁交给容器,而且控制权给容器。对我们来说,我们只是使用的功能。

现在我们使用一下SpringIOC,通过案例进一步了解其思想。

二、代码示例

第一步:添加依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

在这里我使用的是5.2的版本。

第二步:在main文件夹下的resources目录下,新建Spring.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="bean1" class="com.fdd.bean.Benz"/>
    <bean id="bean2" class="com.fdd.bean.BMW"/>
</beans>

注意在这里,我们注入进来了两个bean,一个是奔驰类,一个是宝马类,并分别给他们一个id。只需要这两行代码就相当于把两辆车放到了IOC容器。

第三步:新建一个MyTest测试类

public class MyTest {
    @Test
    public void test1(){
        //首先通过上下文环境和IOC容器链接起来
        ApplicationContext context =
                new ClassPathXmlApplicationContext("Spring.xml");
        //然后在容器内拿去我们想要的bean
        Benz benz = context.getBean("bean1", Benz.class);
        //最后使用我们的bean
        User user = new User(benz);
        user.goHome();
        user.goSchool();
    }
}

案例很简单,首先和容器链接起来,然后拿到我们的bean,最后再去使用,现在你会发现,不管是哪一个用户在什么时候用哪一个bean,都可以从我们的容器内去获取。是不是很简单。

这里只是给出了一个基本的案例,其实关于IOC容器如何管理我们的bean还有很多内容。比如说上面只是简单的注入了一个最普通的bean,如果是由工厂创建的怎么注入,bean里面包含了其他的bean如何注入等等。篇幅有限,今后推出剩余系列的文章。

在这里插入图片描述

发布了256 篇原创文章 · 获赞 75 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/SDDDLLL/article/details/103854697