spring的控制反转和依赖注入

Posted smalljunjun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring的控制反转和依赖注入相关的知识,希望对你有一定的参考价值。

控制反转(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



以上是关于spring的控制反转和依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

浅谈spring框架的控制反转和依赖注入

spring------控制反转(IOC)/依赖注入(DI)

“依赖注入”,“控制反转”是指啥?

轻松了解Spring中的控制反转和依赖注入

c#依赖注入和控制反转的书籍

Spring理论基础-控制反转和依赖注入