今天就跟大家聊聊有關如何在Java中運用依賴注入,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
C++最遭人詬病的地方就是定義一個類需要寫兩個文件,一個.h文件和一個.cpp文件。例如定義一個CMainFrame類,mainframe.h內容如下:
class CMainFrame : public CFrameWndEx
{
protected:
CMainFrame();
public:
virtual ~CMainFrame();
};mainframe.cpp內容如下:
CMainFrame::CMainFrame()
{
}
CMainFrame::~CMainFrame()
{
}當需要給這個類添加一個方法時,需要同時修改.h文件和.cpp文件。例如新增一個DefWindowProc函數。需要在.h文件中增加該函數的聲明。
class CMainFrame : public CFrameWndEx
{
protected:
CMainFrame();
public:
virtual ~CMainFrame();
protected:
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
};mainframe.cpp中增加DefWindowProc的定義:
LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message==WM_NCPAINT )
{
if(bShow){
ShowWindow(SW_SHOW);
}
else {
ShowWindow(SW_HIDE);
}
}
return CFrameWndEx::DefWindowProc(message, wParam, lParam);
}可以看出C++的類定義代碼中,一次變化需要修改兩個文件,其維護的繁瑣令人詬病。
然而Java的出現徹底解決了這個問題,一個類就對應一個.java文件(包括后來其他面向對象語言也秉承了這個思路,比如C#)。
比如一個LogService類用于對日志進行維護,起初只包含日志的增刪功能,LogService.java代碼如下。
public class LogService{
public ServiceResult<Boolean> addLog (SysLogInfo logInfo) {
......
}
public ServiceResult<Boolean> delLog (String id) {
......
}
}當需要增加一個updateLog方法時,僅需對LogService.java進行修改。
public class LogService{
public ServiceResult<Boolean> addLog (SysLogInfo logInfo) {
......
}
public ServiceResult<Boolean> delLog(String id) {
......
}
public ServiceResult<Boolean> updateLog (SysLogInfo logInfo) {
......
}
}一切變得方便了很多。
但是最近在看一些基于Spring(SpringBoot、SpringMVC)框架寫的代碼時,發現很多類的代碼又回到了C++的形式。例如在使用一個LogService時,開發人員首先定義了一個interface,在LogService.java中:
public interface LogService {
ServiceResult<Boolean> addLog(SysLogInfo logInfo);
ServiceResult<Boolean> delLog(String id);
}然后定義了一個該接口的實現類,在LogServiceImpl.java中:
public class LogServiceImpl implements LogService{
@Override
public ServiceResult<Boolean> addLog(SysLogInfo logInfo) {
......
}
@Override
public ServiceResult<Boolean> delLog(String id) {
......
}
}在需要實例化這個類的地方用了一個@Autowired注解注入。
public class LogController {
@Autowired
private LogService logservice;
}在問及開發人員為什么要象這樣做時,其給了一個自信的回答:這是面向接口編程!
注意:這個設計中LogService.java類似于C++中的.h文件,LogServiceImpl.java類似于C++中的.cpp文件,這兩個文件共同定義了一個LogService類。當需要給這個類添加一個updateLog方法時,LogService.java和LogServiceImpl.java都需要被修改,又走回了C++的老路。這顯然是對面向接口編程的曲解。如果這樣都能算面向接口編程的話,那么C++就成了一門天然的面向接口編程的語言,還何必去學那些復雜的設計模式。
不過這樣寫代碼有什么問題嗎?其實也沒有太大問題,只是代碼繁瑣一點而已(C++就是這樣的)。只不過既然你選擇了Java語言,卻又寫成了C++的樣子,就好像在開一輛自動擋的汽車,卻一直撥到手動模式駕駛一樣。
那么什么才是面向接口編程呢,其要點在于:接口是基于變化的抽象。在有可能變化的地方才需要接口。假設上面的例子中,寫日志的動作同時存在3種不同的實現:
1.寫到日志文件。
2.寫到數據庫。
3.寫到本地的一個日志服務的UDP端口。
那么可以基于這個接口寫3個不同的實現類:
public class LogServiceFile implements LogService{
}public class LogServiceDB implements LogService{
}public class LogServiceUdp implements LogService{
}當然此時如果還是使用下面的代碼會報錯,因為Autowired只能裝配對應接口的唯一一個派生類的Bean,而此時存在3個派生類。
public class LogController {
@Autowired
private LogService logservice;
}需要改進成類似下面這個樣子,根據實際情況使用對應的派生類對象:
public class LogController {
private LogService logservice;
void writeLog(SysLogInfo logInfo){
logservice = GetLogServiceInst();
logservice.addLog(logInfo);
}
}1. 簡單,只需理解基本的概念,就可以編寫適合于各種情況的應用程序;2. 面向對象;3. 分布性,Java是面向網絡的語言;4. 魯棒性,java提供自動垃圾收集來進行內存管理,防止程序員在管理內存時容易產生的錯誤。;5. 安全性,用于網絡、分布環境下的Java必須防止病毒的入侵。6. 體系結構中立,只要安裝了Java運行時系統,就可在任意處理器上運行。7. 可移植性,Java可以方便地移植到網絡上的不同機器。8.解釋執行,Java解釋器直接對Java字節碼進行解釋執行。
看完上述內容,你們對如何在Java中運用依賴注入有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。