摘要: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思想方式之一,更多详细说明及实现方法可自行查阅。