Java Web整體梳理-4

簡單認識SpringMVC的工作原理

使用 SpringMVC 框架,實現一個 Controller,並且能夠在瀏覽器中訪問,實在是簡單了太多,背後 SpringMVC 幫我們做了很多的工作,現在簡要地介紹一下,來對 SpringMVC 工作原理有一個初步的認識。

Annotation(註解)

在前面的代碼中,我們使用了諸如 @Controller 等 Annotation。要理解前面的代碼,首先要對 Java 的 Annotation 語法有一定了解。

Annotation,可以翻譯成註解,可以看成對源代碼的一種標註。註解本身不會對源代碼產生任何影響,不過我們可以通過在編譯器或者運行期檢查代碼中的註解,通過註解給代碼引入更多的功能。

Java 語言本身就自帶了一些註解,例如最常見的 @Override,用來標記方法是一個重載方法。以及 @Deprecated 用於標記代碼爲廢棄。

爲了編寫自定義註解,需要使用 Java 提供的若干用於生成註解的註解,即所謂的元註解(Meta Annotations)。簡單理解就是,這些註解存在的作用,就是爲了讓我們可以編寫自己的註解。用一個例子來說明:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {
}

在上面這個例子中,我們使用了若干個註解,來編寫我們自己的 @MyAnnotation 註解,下面簡單介紹一下它們的作用:

  • @Target:指明這個註解可以用在哪些語言元素上,例如方法,類型,函數參數等。
  • @Retention:指明註解的存儲方式,分別是 SOURCE(只存在於代碼中,編譯完成後被丟棄),CLASS(存儲在生成的 class 文件中,但是會被 VM 在運行期丟棄),RUNTIME(存儲在 class 文件中,並且 VM 在運行期間也會保留,因此可以使用反射獲得),默認的存儲方式是 CLASS。
  • @Documented:指明使用了這個註解的代碼,其生成的 Javadoc 中會把此註解展示出來
  • @Inherited:這裏沒有使用,它是用於標記 Target 是 Class 的 Annotation 的,在其他類型的 Annotation 上使用不起作用。它標記對於父類的註解,會被子類做繼承,默認行爲是不繼承。

POJO

Java 語言中引入了很多乍一看奇奇怪怪的概念,POJO 應該算是其中的一個。POJO 全稱是 Plain Old Java Object,即普通的 Java 對象。單看全稱的話,POJO 實在是沒什麼意義,我們隨便寫一個 Java 對象都可以被稱爲 POJO,而事實也正是如此,大部分 Java 對象都可以被稱爲 POJO。那麼 POJO 這個概念實際上存在有什麼意義呢?

想了解這個,首先要知道 POJO 想要對比的是什麼。我們之前提到的 EJB 以及類似的 Java 框架當中,開發者爲了使用框架的功能,需要繼承特定的類,實現特定的接口,這樣產生的依賴相對重的類,就不能被稱爲 POJO。例如在使用 JMS 框架時,爲了實現一個 MessageListener,需要實現特定的接口:

public class ExampleListener implements MessageListener {
    public void onMessage(Message message) {
        // ...
    }
}

再例如,在使用 RMI 時,我們自己的業務接口,也需要繼承自特定的接口:

public interface IHello extends Remote {
    public String helloWorld() throws RemoteException;
}

這樣的設計實際上把業務和框架本身緊緊的耦合在了一起,POJO 的提出就是反對這種設計,鼓勵大家減少這種很重的框架依賴。

SpringMVC 框架是鼓勵使用 POJO 的,例如我們前面編寫的 Controller 類,如果把所有的 Annotation 都去掉,就成了這個樣子:

public class MyFirstSpringController {
    public String Hello() {
        return "Hello, SpringMVC.";
    }
}

可以看到這是一個再簡單不過的 Java 類了,沒有對任何東西產生依賴。而我們前面提到,Annotation 實際上對代碼本身沒有任何影響,因此哪怕加入了諸多 Annotation,這個類本身零依賴的這種輕量性依然不會發生變化。而依賴越輕量的代碼,越容易解耦,在架構上也越清晰,越靈活。這也是 POJO 這個概念想要表達的。

JavaBean

又是一個聽起來很可愛,但是好像又什麼都沒說的 Java 概念。JavaBean 實際上是對於用 Java 編寫數據 Model 時的一種編程慣例,具體的要求是:

  • 有無參的構造器
  • 所有的成員都是 private,對外暴露 getter 和 setter
  • 實現 Serializable

後面 JavaBean 這個概念也逐漸的泛化,不再侷限於 Model 類,出現了所謂的業務 Bean 等,對於 Serializable 的要求也顯得可有可無。還是拿我們的 Controller 類舉例子,它不僅僅是一個 POJO,也是一個 JavaBean。

Spring 把很多東西包括自己的一些組件也都稱爲 Bean,這個稱呼可以看成是對 JavaBean 的進一步泛化。

SpringMVC Magic

首先 SpringMVC 需要知道我們的 Controller 是什麼。前面我們在配置文件裏標明瞭我們的 Controller 類是什麼。

在 Controller 類中,對於請求的分發處理,@RequestMapping 的作用很明顯。在初始化 Controller 的時候,SpringMVC 把 @RequestMapping 註解當中的信息進行處理,之後就可以根據這些信息,把請求分發到對應的 Controller 當中的對應方法裏。

@ResponseBody 表明函數的返回值應該被用作 HTTP 返回的 body 處理。SpringMVC 用我們返回的字符串生成 HTTP 響應,返回給了客戶端。

這就是 SpringMVC 大體的工作流程,可以看到 SpringMVC 通過 Annotation 以一種低侵入性的方式,提供了一套簡潔好用的 Web 開發的 API。

發佈了19 篇原創文章 · 獲贊 4 · 訪問量 1777
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章