一、IOC思想
这是一例控制权在程序员手里的程序:
1.1 路径
1.2 程序
UserDao:
package com.duzhuan.springLearn.dao;
/**
* @Autord: HuangDekai
* @Date: 2020/9/22 14:48
* @Version: 1.0
* @since: jdk11
*/
public interface UserDao {
void getUser();
}
UserDaoImpl:
package com.duzhuan.springLearn.dao;
/**
* @Autord: HuangDekai
* @Date: 2020/9/22 14:51
* @Version: 1.0
* @since: jdk11
*/
public class UserDaoImpl implements UserDao {
@Override
public void getUser() {
System.out.println("Get User By: ---------------------> UserDaoImpl");
}
}
UserService:
package com.duzhuan.springLearn.service;
/**
* @Autord: HuangDekai
* @Date: 2020/9/22 14:50
* @Version: 1.0
* @since: jdk11
*/
public interface UserService {
void getUser();
}
UserServiceImpl:
package com.duzhuan.springLearn.service;
import com.duzhuan.springLearn.dao.UserDao;
import com.duzhuan.springLearn.dao.UserDaoImpl;
/**
* @Autord: HuangDekai
* @Date: 2020/9/22 14:53
* @Version: 1.0
* @since: jdk11
*/
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
1.3 问题
那么由于客户的需求,现在UserDao需要改为MySQL查询功能,即新增一个实现并使用他:
路径
代码
package com.duzhuan.springLearn.dao;
/**
* @Autord: HuangDekai
* @Date: 2020/9/22 15:13
* @Version: 1.0
* @since: jdk11
*/
public class UserDaoMySQLImpl implements UserDao {
@Override
public void getUser() {
System.out.println("Get User By: ---------------------> UserDaoMySQLImpl");
}
}
这时候问题就来了,用户是不能访问DAO层的,实际调用的是Service层:
那么这个时候就需要修改业务层实现UserServiceImpl的代码:
package com.duzhuan.springLearn.service;
import com.duzhuan.springLearn.dao.UserDao;
import com.duzhuan.springLearn.dao.UserDaoImpl;
import com.duzhuan.springLearn.dao.UserDaoMySQLImpl;
/**
* @Autord: HuangDekai
* @Date: 2020/9/22 14:53
* @Version: 1.0
* @since: jdk11
*/
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoMySQLImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
使用测试案例:
这样是很有问题的。
Java Web中有一个著名的开闭原则:软件实体(类、函数、接口等)可以扩展,但不能修改。
因为这个示例里只有一处修改。而在实际中成千上万行的代码里面去修改显然是十分耗费时间和精力的。
1.4 IoC思路
package com.duzhuan.springLearn.service;
import com.duzhuan.springLearn.dao.UserDao;
/**
* @Autord: HuangDekai
* @Date: 2020/9/22 14:53
* @Version: 1.0
* @since: jdk11
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
利用setter进行动态实现的注入。
看起来虽然没多大改变,但在IoC思想方面,这是天翻地覆的变革。
简单地说,就是创建的对象的权力由程序员(new
一个对象)变成了由使用者注入一个对象。程序不再有主动性,而是变成了被动地接受对象。
扩展起来就是:程序员不用再去管理对象的创建了。
那么,相应的,测试样例变成:
import com.duzhuan.springLearn.dao.UserDaoMySQLImpl;
import com.duzhuan.springLearn.service.UserServiceImpl;
import org.junit.Test;
/**
* @Autord: HuangDekai
* @Date: 2020/9/22 14:57
* @Version: 1.0
* @since: jdk11
*/
public class UserServiceTest {
@Test
public void getUser(){
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDao(new UserDaoMySQLImpl());
userService.getUser();
}
}
此时,如果再加入一个Oracle实现:
package com.duzhuan.springLearn.dao;
/**
* @Autord: HuangDekai
* @Date: 2020/9/22 16:12
* @Version: 1.0
* @since: jdk11
*/
public class UserDaoOracleImpl implements UserDao {
@Override
public void getUser() {
System.out.println("Get User By: ---------------------> UserDaoOracleImpl");
}
}
那么,要修改的仅仅就是调用的代码,此处即测试样例:
import com.duzhuan.springLearn.dao.UserDaoMySQLImpl;
import com.duzhuan.springLearn.dao.UserDaoOracleImpl;
import com.duzhuan.springLearn.service.UserServiceImpl;
import org.junit.Test;
/**
* @Autord: HuangDekai
* @Date: 2020/9/22 14:57
* @Version: 1.0
* @since: jdk11
*/
public class UserServiceTest {
@Test
public void getUser(){
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDao(new UserDaoOracleImpl());
userService.getUser();
}
}