依賴注入原理,作用,注入方式——Spring IOC/DI(二)
依賴注入原理,作用,注入方式
前言
上一章我們講到了IOC和DI概述:
https://blog.csdn.net/qq_34598667/article/details/83275560
這一章接上一章繼續講
依賴注入(Dependency Injection)是用於實現控制反轉(Inversion of Control)的最常見的方式之一。本文主要在於介紹依賴注入的含義以及原理,為初學者理清頭緒
為什麼需要依賴注入?
第一個問題,上一章我們主要介紹了控制反轉的含義,依賴注入實現了控制反轉,那麼控制反轉的作用是什麼?——解耦
那麼問題有來了,依賴注入如何實現解耦呢?
首先我們來看一下在沒有使用依賴注入下的程式碼,順便給大家回顧一下耦合的概念
什麼是耦合度?
物件之間的關係,通常說當一個模組(物件)更改時也需要更改其他模組(物件),這就是耦合,耦合度過高會使程式碼的維護成本增加。要儘量解耦
舉例說明:
public class UserService{
//建立dao介面引用指向實現類物件--直接建立物件
private UserDao userDao=new UserDaoImpl();
//呼叫dao方法 返回一個User物件
public User login(String userName,String password){
return userDao.login(userName,password);
}
}
仔細觀察上述程式碼:
我們在UserService中建立了一個登陸的login方法,但是實際上完成登陸功能的是UserDaoImpl的登入login方法。我們使用UserDaoImpl的login方法時是直接建立了一個屬性UserDao的方式(也有人使用無參構造,在無參構造中使用new建立物件)
那麼問題來了,如果現在我需要修改UserDaoImpl的構造方式,在例項化時新增一個屬性作為引數,那麼我不僅要修改UserDaoImpl中的程式碼,還要修改所有與UserService中相同的建立UserDaoImpl型別物件的程式碼。
這種在UserService中建立UserDaoImpl的方式,不僅讓UserService依賴於UserDao介面,還依賴於UserDaoImpl。這種就是耦合度過高的體現,也是依賴注入需要解決的問題。
耦合度過高帶來的問題
1、修改一處程式碼會導致很多程式碼都要修改,修改不方面
2、無法單獨測試
3、可讀性差(如果一段程式碼不便於測試,那麼它一定不便於閱讀)
依賴注入的方式
拔掉外衣看依賴注入,其實它並不複雜,相反其實我們在很多地方都寫過,這裡介紹一下依賴注入的三種方式:
1)構造器注入
我們修改一下上面的程式碼,讓UserService只依賴於UserDao介面,而不依賴與UserDaoImpl實現類
public class UserService{
//建立dao介面引用指向實現類物件--直接建立物件
private UserDao userDao;
//使用有參構造方法
public UserService(UserDao userDao){
this.userDao=userDao;
}
}
2)setter注入
同樣的,我們也可以使用增加一個setter的方式來傳入一個建立好的UserDaoImpl物件
public class UserService{
//建立dao介面引用指向實現類物件--直接建立物件
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
}
3)介面注入
介面注入是使用介面來提供setter方法,首先得建立一個介面
public interface InjectDao{
void injectDaoImpl(UserDao userDao);
}
然後讓UserService實現該介面
public class UserService implements InjectDao{
//建立dao介面引用指向實現類物件--直接建立物件
private UserDao userDao;
public void injectDaoImpl(UserDao userDao){
this.userDao=userDao;
}
}
最後,重點是我們要根據不用的框架來完成依賴注入。
總結
把對抽象介面型別的物件的賦值放在類外面,把new出來的物件放在外面傳入進來,那就不用依賴具體的實現類。
下一章,Spring中完成依賴注入的方式:
https://blog.csdn.net/qq_34598667/article/details/83308071