IOC


只导入SpringWeb包有一个好处,可以直接自动导入其他所有包

在以往我们写普通的MVC程序时,需要按照以下步骤进行编写

  1. UserDao接口
  2. UserDaoImpl实现类
  3. UserService接口
  4. UserServiceImpl业务实现类

这样做有一个弊端,请看这个例子:

我们想要通过SqlSever查询用户,首先我们要编写Dao接口:

public interface UserDao {
    void getUser();
}

再写他的实现类:

public class UserDaoImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("通过SqlServer获得了用户数据");
    }
}

做好之后再去写Service层

Service接口:

public interface UserService {
   void getUser();
}

Service接口实现:

我们在这里新建封装好的Dao层

public class UserServiceImpl implements UserService {
    @Override
    public void getUser() {
        UserDao userDao = new UserDaoImpl();
        userDao.getUser();
    }
}

这时候,我们的客户突然发过来一个请求,他希望使用Mysql的方式进行查询数据,好吧,我们只好照做

我们根据上面的流程,首先要多写一个Dao实现类

public class UserDaoMysqlImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("Mysql获取用户数据");
    }
}

之后还要在Service层的实现类里更改代码(最恶心最麻烦最头疼的部分)

public class UserServiceImpl implements UserService {
    @Override
    public void getUser() {
        //UserDao userDao = new UserDaoImpl();
        //这里要新创建一个Mysql的实现类
        UserDao userDao = new UserDaoMysqlImpl();
        userDao.getUser();
    }
}

但是停一下朋友,如果客户再次更改需求了呢,要求用Orcal查询用户了呢,难道我们每一次都要去这样更改Dao层代码么??

显然这是一种不好的程序格式,因此我们需要进行Set注入

我们在service的实现类里加上

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

这样,当我们的用户再次更改业务需求,例如更换了十万种数据库,我们都不需要更改底层代码,我们只需要在使用时使用Set加上需要的Dao层实现类的Class对象就好了。

public void testIOC(){
    UserServiceImpl userService = new UserServiceImpl();
    userService.setUserDao(new UserDaoOrcalImpl());
    userService.getUser();
}

我们将创建对象的控制权从程序员的手中推给了运行时的代码,这就是控制反转(IOC)

IOC本质:是一种将程序主动权交给用户的一种设计思想

DI(依赖注入):是实现IOC的一种方法


醉后不知天在水,满船清梦压星河