Spring控制反转(IOC)

摘要:Spring笔记_02-2021-06-27,笔记内容均为观看B站视频@狂神说

1.理论

控制反转:

​ 即控制权的转移,将我们创建对象的方式反转了,以前对象的创建是由我们开发人员自己维护,包括依赖关系也是自己注入。使用了spring之后,对象的创建以及依赖关系可以由spring完成创建以及注入,反转控制就是反转了对象的创建方式,从我们自己创建反转给了程序创建(spring)。一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。

2.推导

详细推导过程地址:公众hao搜索@狂神说

2.1 没有使用控制反转思想(IOC)

1.新建一个接口UserDao以及实现类UserDaoImpl

package com.riove.dao;

public interface UserDao {

    void getUser();

}
package com.riove.dao;

public class UserDaoImpl implements UserDao{

    public void getUser() {
        System.out.println("SqlServer数据库!");
    }

}

2.新建一个接口UserService以及实现类UserServiceImpl

package com.riove.service;

public interface UserService {

    void getUser();

}
package com.riove.service;

import com.riove.dao.UserDao;
import com.riove.dao.UserDaoImpl;

public class UserServiceImpl implements UserService{

    UserDao userDao = new UserDaoImpl();

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

3.测试(重点,注意区别)

package com.riove.test;

import com.riove.service.UserService;
import com.riove.service.UserServiceImpl;
import org.junit.Test;

public class IocTest {

    @Test
    public void test1() {
        /**
         *1.初学时,我们一般都是通过将UserService接口的实现类实例化一个对象,然后通过这个对象调用方法,如下:
         *此时:[new UserServiceImpl()]这个对象是由我们去new,也就是说这个是在编写代码的过程中固定好的,写死的
         */
        //假设有多个实现类,该怎么办?能不能通过动态的获取用户需要完成业务的实现类
        UserService userService = new UserServiceImpl();	
        //2.通过获得的对象,调用方法,实现业务
        userService.getUser();
    }
}

2.2 使用控制反转思想(IOC)

1.新建一个接口UserDao以及实现类UserDaoImpl、UserDaoImpl2、UserDaoImpl3

package com.riove.dao;

public interface UserDao {

    void getUser();

}
package com.riove.dao;

public class UserDaoImpl implements UserDao{

    public void getUser() {
        System.out.println("SqlServer数据库!");
    }

}
package com.riove.dao;

public class UserDaoImpl1 implements UserDao{

    public void getUser() {
        System.out.println("MySql数据库!");
    }

}
package com.riove.dao;

public class UserDaoImpl2 implements UserDao{

    public void getUser() {
        System.out.println("Oracle数据库!");
    }

}

2.新建一个接口UserService以及实现类UserServiceImpl

package com.riove.service;

import com.riove.dao.UserDao;

public interface UserService {

    void getUser();
    void setUserDao(UserDao userDao);

}
package com.riove.service;

import com.riove.dao.UserDao;
import com.riove.dao.UserDaoImpl;
import com.riove.dao.UserDaoImpl2;
import com.riove.dao.UserDaoImpl3;

public class UserServiceImpl implements UserService{

    //1.通过工厂模式的思想,我们可以在Service层定义一个类型为:UserDao   变量名:userDao
    private UserDao userDao;
    //2.重点,IOC注入的方式,通过1)Setter  2)构造方法注入   3)字段注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    /**
     * 3.思考:
     * 此时我们并没有固定是哪一个dao实现类:UserDaoImpl/UserDaoImpl2/UserDaoImpl3
     * 那么怎么知道我们需要那个dao实现类呢,这就需要外部传入,即程序被动的接收,而不是在编写的时候固定死
     */
    public void getUser() {
        userDao.getUser();
    }

}

3.测试(注意查看,通过IOC如何)

package com.riove.test;

import com.riove.dao.UserDaoImpl;
import com.riove.dao.UserDaoImpl2;
import com.riove.dao.UserDaoImpl3;
import com.riove.service.UserService;
import com.riove.service.UserServiceImpl;
import org.junit.Test;

public class IocTest {

    @Test
    public void test1() {
        //1.我们需要实现输出“SqlServer数据库!”,即实例化UserDaoImpl对象,这里我们已经实现
        UserService userService = new UserServiceImpl();
        //2.输出“SqlServer数据库!”
        userService.getUser();
        /*3.
         *此时,我们需要实现输出“MySql数据库!”,那么我们需要去修改我们的代码,那么其它需求呢,总不能改变一个需求就去修改代码吧!
         *其二,面对用户不同的需求,我们不可能让用户去改吧!
         */
    }
    @Test
    public void test2() {
        //1.Ioc的思想让我们不用去修改内部程序代码
        UserService userService = new UserServiceImpl();
        /*2.我们需要实现那个业务,比如:输出“SqlServer数据库!”,那么通过set方法传入该dao实现类UserDaoImpl即可
                                   输出“MySQL!”,那么通过set方法传入该dao实现类UserDaoImpl2即可
                                   输出“Oracle数据库!”,那么通过set方法传入该dao实现类UserDaoImpl3即可
         */
        //输出“SqlServer数据库!”,那么通过set方法传入该dao实现类UserDaoImpl
        userService.setUserDao(new UserDaoImpl());
        userService.getUser();
        //输出“MySQL!”,那么通过set方法传入该dao实现类UserDaoImpl2
        userService.setUserDao(new UserDaoImpl2());
        userService.getUser();
        //输出“Oracle数据库!”,那么通过set方法传入该dao实现类UserDaoImpl3
        userService.setUserDao(new UserDaoImpl3());
        userService.getUser();
    }
}

3.小结

控制反转(Ioc):这个推导过程中使用的方式,仅仅是实现IOC思想方式之一,更多详细说明及实现方法可自行查阅。

上一篇:Mybatis-Plus快速入门


下一篇:6.9 第二天 springboot