IOC理论
代码实例测试
在JavaWeb的MVC结构中实现一个接口需要一下几个部分
- Dao
- DaoImpl
- Service
- ServiceImpl
假设dao接口针对不同数据库有多个实现类,但是Service层需要调用dao层,然而是通过自己new一个dao层对象实现的,如果更换数据库实现类时会涉及到相关所有service层代码。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D2ALD1Jo-1614693776252)(Spring学习/image-20210302214746031.png)]
dao层接口:
package dao;
public interface UserDao {
public void getUser();
}
不同实现:
package dao;
public class UserDaoImplMysql implements UserDao{
@Override
public void getUser() {
System.out.println("Mysql====>getUser");
}
}
package dao;
public class UserDaoImplRedis implements UserDao{
@Override
public void getUser() {
System.out.println("Redis====>getUser");
}
}
package dao;
public class UserDaoImplSqlserver implements UserDao{
@Override
public void getUser() {
System.out.println("Sqlserver====>getUser");
}
}
service层:
package service;
import dao.UserDao;
import dao.UserDaoImplMysql;
public class UserServiceImpl implements UserService{
UserDao userDao = new UserDaoImplMysql();
@Override
public void getUser() {
userDao.getUser();
}
}
这样会显得很麻烦,因此我们可以在service层增加一个接口,也就是不为userdao实例对象,而是交给我们来设置,也就变成了:
package service;
import dao.UserDao;
public class UserServiceImpl implements UserService{
UserDao userDao = null;
@Override
public void getUser() {
userDao.getUser();
}
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
}
测试类:
import dao.UserDaoImplMysql;
import dao.UserDaoImplRedis;
import service.UserService;
import service.UserServiceImpl;
public class MyTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.setUserDao(new UserDaoImplRedis());
userService.getUser();
userService.setUserDao(new UserDaoImplMysql());
userService.getUser();
}
}
控制权原本在service层程序的,因为他自己创建了dao层对象,但是现在他提供了一个接口来设置userdao指向的具体实现类
控制权就转移到了测试类手中,测试类负责注入了userdao具体实现,如此便实现了控制反转
理论知识
底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑。
对象之间耦合度过高的系统,必然会出现牵一发而动全身的情形。
添加一层中间商之后的系统:
假设A对象依赖于对象B的一些东西,IOC容器完成一些操作,也就是依赖注入!