详解SpringIOC容器相关知识

论坛 期权论坛 脚本     
niminba   2021-5-23 03:55   1077   0

一、前言

IOC控制反转,不是一种技术,而是一种设计思想,就是将原本在程序中手动创建对象的控制权,交给Spring框架来管理。

区别:

  • 没有IOC的思路:若要使用某个对象,就必须自己负责去写对象的创建
  • IOC的思路:若要使用某个对象,只需要从Spring容器中获取需要使用的对象,不关心对象的创建过程,也就是把创建对象的控制权交给了Spring框架。
  • 好莱坞法则:Don't call me, I 'll call you

举例说明:

做菜,做蒜薹炒猪肉

你有两种做法:

第一种,自己养猪,然后种蒜薹。等到猪长大了,你就可以杀猪,蒜薹成熟了,就收割。然后开始炒,做成了蒜薹炒猪肉。

第二种,从农贸市场获取猪和蒜薹,拿回来直接炒,做成了蒜薹炒猪肉。

此时的IOC就相当于这个农贸市场,我要做菜,我去农贸市场拿过来就可以了,而不需要自己去弄。为什么要Java对象放到容器里?因为我们要做到拿来即用,便于管理。那你能管理农贸市场吗?你不能,那谁来管农贸市场?Spring!这就是控制反转IOC,我们把控制权交给了Spring框架,他来帮我们管这个农贸市场,他来养猪,他来种菜。我们只需在要菜的时候,去市场买就好了。

再举一个例子

过年了,想要给家里打扫个卫生,你想请几个钟点工来打扫。也有两种做法。

第一种:自己主动找,找身边人看看谁认识钟点工,你自己打电话邀约,谈价格

第二种:直接找家政公司,直接提出需求即可。

第一种方式就是我们自己创建对象的方式,自己主动new几个钟点工。而第二种就是spring给我们提供的IOC方式,家政公司就是一个容器,能给我提供很多的服务,钟点工对象是spring帮我们创建的。

又过了几天,我又想给厨房的油烟机清理一下,也能直接打电话给家政公司,提出需求。

那上述例子中的农贸市场和家政公司哪里来啊?

我们可以自己构建,就像自己成立一个公司一样。具体在程序中表现为:

1.使用配置文件或者注解的方式定义一下我们自己容器里存放的东西。

或者去别人的公司里找。具体在程序中表现为:

2.一定有很多人创建了自己的公司,这些服务都可以集成在我们自己的容器里,为我们提供强大的功能,比如spring自带很多的template模板类。

二、IOC原理实战

首先在pom.xml文件中加入spring的相关jar包。

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>
</dependencies>

我们定义我们的接口和实现类

// UserDao接口
public interface UserDao {
    void getUser();
}
// UserDao实现类1,mysql实现
public class UserDaoImpl implements UserDao {
    public void getUser() {
        System.out.println("mysql实现");
    }
}
// UserDao实现类2,oracle实现
public class UserDaoImpl implements UserDao {
    public void getUser() {
        System.out.println("oracle实现");
    }
}

然后我们的业务实现类,在不使用set注入的情况下,是这样的:

//业务接口
public interface UserService {
    void getUser();
}
//业务实现类
public class UserServiceImpl implements UserService {
    //传统的方法中,如果这边要改变,那就必须将这里的语句改变才可以
    private UserDao userDao = new UserDaoImpl();

    public void getUser() {
        userDao.getUser();
    }
}

对应的测试类:

public class MyTest {
    public static void main(String[] args) {
        //用户实际调用的是业务层,不需要接触dao层
        UserServiceImpl userService =new UserServiceImpl();
        userService.getUser();
    }
}

但是你会发现使用这种方法如果我在测试这里想用oracle实现,那就必须新增一个业务实现类或者修改我原本的业务实现类,违反了开闭原则。

所以我们的业务实现类要使用set方法动态注入我们的UserDao实现类。

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    // 利用set进行动态实现值的注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void getUser() {
        userDao.getUser();
    }
}

如此一来只需要在测试类中通过set方法,传入对应的实现类对象,就可以实现调用不同的实现对Т77FV&V7G&Т>Тi[yN&[yBТyN[~iyN&yBТ&SУFcУKVyK7&[[nKNyK7&[~yN[ inX8#У#N8[#У~XnihnZyNX[{NyJz[i[hnX[yN&i&X[yN8#У[K[Z*XyNhKnZУYnk:XZ^i6WNikk9^ik:XZSУ>izh ;>KXyN{zX*XyNhKn8#УKNyVznKnZyNj~[{[{.{&zn8#У7GFWBv6V"#YhY~h"7&3GG3F&'22V"cS&C##f3sSSSSs3c63fC6Sr#У >yDXijh.hZyK7&X[ynY(8^X#УjX[>Knz57&yX[>yyNih~z[ K{NZIyX[57&Xh^Z{J.zKK^XNih~zhn{~{XyNyX[>ih~z[ZJ~Z^YZIiJ

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP