Spring中的IoC是一种思想。所谓控制反转,也就是从创建对象的主动权在程序员手中,到创建对象的主动权在用户手中。控制反转官方定义是一种通过描述(XML或注解)并通过第三方生产或获取特定对象的方式,在Spring中实现控制反转的是IoC容器,其实现方式是依赖注入(Dependence Injection,DI)。
我在这里以代码和需求的形势进行阐述
首先我在Dao层写一个UserDao的接口里面有一个方法
package com.zhiying.dao;
public interface UserDao {
public void getUser();
}
然后写一个UserDaoImpl的类来实现这个接口,并输出一句话
package com.zhiying.dao;
public class UserDaoImpl implements UserDao {
public void getUser() {
System.out.println("this is a user");
}
}
现在我们开始写Service层,这里写一个UserService的接口,并定义一个方法
package com.zhiying.service;
public interface UserService {
public void getUser();
}
然后写一个UserServiceImpl的实现类
package com.zhiying.service;
import com.zhiying.dao.UserDao;
import com.zhiying.dao.UserDaoImpl;
public class UserServiceImpl implements UserService {
UserDao userDao = new UserDaoImpl();
public void getUser() {
userDao.getUser();
}
}
下面开始测试:
import com.zhiying.service.UserService;
import com.zhiying.service.UserServiceImpl;
public class MyTest {
public static void main(String[] args) {
UserService userService= new UserServiceImpl();
userService.getUser();
}
}
测试结果如下,也正是我们所料
但如果我们想要不同的用户去实现该接口呢,例如我们要Mysql用户去实现
package com.zhiying.dao;
public class UserDaoMysqlImpl implements UserDao {
public void getUser() {
System.out.println("this is a mysql");
}
}
这时候我们就需要去修改Service层的方法,结果如下
package com.zhiying.service;
import com.zhiying.dao.UserDao;
import com.zhiying.dao.UserDaoImpl;
import com.zhiying.dao.UserDaoMysqlImpl;
public class UserServiceImpl implements UserService {
//UserDao userDao = new UserDaoImpl();
UserDao userDao = new UserDaoMysqlImpl();
public void getUser() {
userDao.getUser();
}
}
然后测试结果如下:
虽然得到了我们想要的结果,但是这里需要改Service层的代码,很不好,所以就有了面向切面编程的IOC思想,用一个set注入
把UserService接口和UserServiceImpl类改为如下
package com.zhiying.service;
import com.zhiying.dao.UserDao;
public interface UserService {
public void setUserDao(UserDao userDao);
public void getUser();
}
package com.zhiying.service;
import com.zhiying.dao.UserDao;
import com.zhiying.dao.UserDaoImpl;
import com.zhiying.dao.UserDaoMysqlImpl;
public class UserServiceImpl implements UserService {
//UserDao userDao = new UserDaoImpl();
//UserDao userDao = new UserDaoMysqlImpl();
UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void getUser() {
userDao.getUser();
}
}
这时候,把测试类也需要修改,这时候的主动权就在用户手中了,用户可以自定义的调用
import com.zhiying.dao.UserDaoImpl;
import com.zhiying.dao.UserDaoMysqlImpl;
import com.zhiying.service.UserService;
import com.zhiying.service.UserServiceImpl;
public class MyTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.setUserDao(new UserDaoMysqlImpl());
userService.getUser();
userService.setUserDao(new UserDaoImpl());
userService.getUser();
}
}
这样就实现了,添加新的UserDao实现,也不用改Service层的代码了,而且想实现谁用户可以自定义。