1. 先看一个案例
Pojo 实体类
package com.lmy.pojo;
public class User {
public int id;
public String name;
public User(String name) {
this.name = name;
}
}
Dao 接口
package com.lmy.dao;
import com.lmy.pojo.User;
public interface UserDao {
User selectUser();
}
Dao 实现
package com.lmy.dao;
import com.lmy.pojo.User;
public class UserDaoImpl implements UserDao{
public User selectUser() {
System.out.println("从默认数据库查询");
return new User("独行者");
}
}
package com.lmy.dao;
import com.lmy.pojo.User;
public class UserDaoMysqlImpl implements UserDao{
public User selectUser() {
System.out.println("从Mysql数据库查询");
return new User("独行者");
}
}
package com.lmy.dao;
import com.lmy.pojo.User;
public class UserDaoOracleImpl implements UserDao{
public User selectUser() {
System.out.println("从Oracle数据库查询");
return new User("独行者");
}
}
package com.lmy.dao;
import com.lmy.pojo.User;
public class UserDaoExcelImpl implements UserDao{
public User selectUser() {
System.out.println("从Excel数据库查询");
return new User("独行者");
}
}
Service 业务接口
package com.lmy.service;
import com.lmy.pojo.User;
public interface UserService {
User selectUser();
}
Service 业务实现
package com.lmy.service;
import com.lmy.dao.*;
import com.lmy.pojo.User;
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl() {
userDao = new UserDaoImpl();
userDao = new UserDaoExcelImpl();
userDao = new UserDaoOracleImpl();
userDao = new UserDaoMysqlImpl();
}
public User selectUser() {
return userDao.selectUser();
}
}
测试
package com.lmy.test;
import com.lmy.service.UserService;
import com.lmy.service.UserServiceImpl;
public class MyTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
System.out.println(userService.selectUser().name);
}
}
用户需求 用户的需求经常变更 第一天他说MySQL比较好,想用MySQL查询数据 第二天他说Oracle比较牛,想用Oracle查询数据 第三天他说Excel比较简单,想用Excel查询数据 第四天他说MySQL比较好,又想用MySQL查询数据 用户需要每变更一次,在需要重新设置userDao的实现类
public UserServiceImpl() {
userDao = new UserDaoImpl();
userDao = new UserDaoExcelImpl();
userDao = new UserDaoOracleImpl();
userDao = new UserDaoMysqlImpl();
}
只有一个查询业务还好说,如果成百上千个Service(业务 登录业务 用户业务 产品业务) 也就是有成百上千个地方在new userDao 每一个Service都要改一下userDao的实现(重新new) 那就是一个灾难
2. 解决问题
如何解决上述问题,首先想到的是让用户自己去选择去使用哪个数据库 Service 业务层修改
package com.lmy.service;
import com.lmy.dao.UserDao;
import com.lmy.pojo.User;
public interface UserService {
void setUserDao(UserDao userDao);
User selectUser();
}
package com.lmy.service;
import com.lmy.dao.*;
import com.lmy.pojo.User;
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl() {
userDao = new UserDaoImpl();
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public User selectUser() {
return userDao.selectUser();
}
}
再次测试,这里相当于用户调用,用户来选择使用哪个数据库
public class MyTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.setUserDao(new UserDaoImpl());
userService.setUserDao(new UserDaoMysqlImpl());
userService.setUserDao(new UserDaoOracleImpl());
userService.setUserDao(new UserDaoExcelImpl());
System.out.println(userService.selectUser().name);
}
}
这个就相当于控制反转IOC的原型 之前代码主动权在业务层 Service 现在代码主动权在用户的 Test
3. 总结
控制反转是一种通过描述(XML或注解)并通过第三方生产或获取特定对象的方式 在Spring中实现控制反转的是IOC容器,实现方法是依赖注入DI
|