Spring 详解(一)

发布于 2021-07-29  280 次阅读


IoC(重点)

控制反转 - IoC(Inversion of Control)是一种设计思想,DI(依赖注入)是实现 IoC 的一种方法。在没有 IoC 的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方。可以点击后方链接了解 IoC。https://zhuanlan.zhihu.com/p/75029076

Spring 容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从 Ioc 容器中取出需要的对象。

准备工作

之前在 JavaWeb 基础(一) 中就说过要做啥准备工作,这里就不再次说明了。新建一个不基于模板的 maven 项目,并添加下面的依赖。

<dependencies>
    <!--单元测试依赖-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <!--Spring 依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.8</version>
    </dependency>
</dependencies>

分析 IoC 实现

之前的项目

Dao 层只有一个接口一个实现类,Service 层同样也是。

public interface UserDao {
    public void getUser();
}
public class UserDaoImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("获取用户数据。");
    }
}
public interface UserService {
    public void getUser();
}
public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoImpl();

    @Override
    public void getUser() {
        userDao.getUser();
    }
}
//测试
@Test
public void test(){
    UserService userService = new UserServiceImpl();
    userService.getUser();
}

现在的项目

如果 Dao 的接口有多个实现类时,UserServiceImpl 代码该如何修改?

//添加新的 Dao 实现类
public class UserDaoMySqlImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("MySql 获取用户数据。");
    }
}
public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoMySqlImpl();    //new 的对象变成了一个新的 Dao 实现类

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

这就需要在 Service 层的实现类修改对应的实现,假设我们的这种需求非常大,这种方式就根本不适用了。每次变动 , 都需要修改大量代码,这种设计的耦合性太高,牵一发而动全身。

那我们如何去解决呢?我们可以在 Service 层的实现类创建 Dao 的引用属性,不去实例化 Dao 对象,而是留一个 set 方法,通过 set 方法传入不同的 Dao 实现类对象。

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void getUser() {
        userDao.getUser();
    }
}
//测试
@Test
public void test(){
    UserServiceImpl userService = new UserServiceImpl();
    //通过 set 方法传入不同的 Dao 实现类对象
    userService.setUserDao(new UserDaoImpl());
    userService.getUser();
    userService.setUserDao(new UserDaoMySqlImpl());
    userService.getUser();
}

这种思想从本质上解决了问题,我们程序员不再去管理对象的创建,更多的是去关注业务的实现,耦合性大大降低,这也就是 IoC 的原型。