控制反转(Inversion of Control,IOC)
我们首先先来了解一下控制二字,也就是在控制“正”转的情况下,在任何一个有请求作用的系统当中,至少需要有两个类互相配合工作,在一个入口类下使用new关键字创建另一个类的对象实例,这就好比在面向对象编程的思想下,“我“充当一个入口类,在这个入口类中,我每次吃饭的时候都要买一双一次性筷子(每一次使用都要new一次),在这样的关系下,是”我“(即调用者)每次都要”主动“去买一次性筷子(另一个类),我对筷子说你老老实实的过来我的手上,是我控制了筷子,那好,在这种控制正转的关系下,放在现实生活当中,肯定是不现实的,而且人是懒惰的,他总会去创造出更加方便自己生活的想法,更确切的做法是,买一双普通的筷子(非一次性),把他放在一个容器当中(在Spring中叫做IOC容器),你需要使用的时候就对容器说:IOC我想要用筷子(向容器发出请求),接着筷子就会”注入“到的手上,而在这个过程当中,你不再是控制方,反而演变成一名请求者(虽然本身还是调用者),依赖于容器给予你资源,控制权坐落到了容器身上,于是这就是人们俗称的控制反转。
简单来说就是把对象创建、管理的控制权都交给Spring容器,这是一种控制权的反转。
自己控制:
@RestController @RequestMapping("/student/api") public class UserController { UserService userService=new UserServiceImp(); @PostMapping(value="/all") public List<User> getAll(@RequestBody Map<String, Object> params){ List<User> userAll=userService.getUsers(); return userAll; } }
交给IOC容器控制,你只负责请求,它返回给你就好
IOC容器:
它负责了对象整个的生命周期的管理——创建、装配、销毁。
@RestController @RequestMapping("/student/api") public class UserController { @Autowired UserService userService; @PostMapping(value="/all") public List<User> getAll(@RequestBody Map<String, Object> params){ List<User> userAll=userService.getUsers(); return userAll; } }
@Autowired就是从IOC容器中请求这个bean。
依赖注入(Dependency Injection)
我们所需求的对象,需要依赖容器来获得,这个过程即是依赖注入。本质上IOC和DI是同一思想下不同维度的表现。
依赖注入有构造注入,setter注入,接口注入,spring中的注解注入
构造注入:
public class UserMessage { UserDao userDao; public UserMessage(){ userDao=new UserDao(); } public void addUser(String username){ userDao.addUser(username); } }
由于在UserMessage内部创建了UseDao对象,这就造成了两个类之间的耦合度较高。
setter注入:
public interface UserDao{ void addUser(String username); } public class UserDaoImpl implements UserDao{ @Override public void addUser(String username) { System.out.println("添加用户:"+username); } } public class UserMessage{ private UserDao userDao; //使用设值方式赋值 public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void addUser(String userName, String password) { userDao.addUser(userName); } } public class test{ public static void main(String[] args) { UserDao userDao =new UserDaoImpl(); UserMessage userMessage=new UserMessage(); userMessage.setUserDao(userDao); } }
降低了User Message和UserDao的耦合度,需要换另一种UserDao的实现类的话,我们只需要修改test类下的第一行的代码就可以了,UserMessage内部并不需要修改。
注解注入
@Configuration public class UserConfig { @Bean public UserDao getUserDao(){ return new UserDao(); } @Bean public UserMessage getUserMessage(){ return new UserMesssgae(getUserDao); } }
参考:
https://www.cnblogs.com/chenbenbuyi/p/8166304.html
https://www.cnblogs.com/xxzhuang/p/5948902.html
https://www.jianshu.com/p/506dcd94d4f9
原文地址:https://www.cnblogs.com/smallJunJun/p/10127943.html