傳統Servlet應用:
Servlet元件
對映url(@WebServlet)
實現(繼承HTTPServlet)
Servlet註冊
Servlet 註解 (@ServletComponentScan)
Spring Bean
Registration Bean
非同步非阻塞
非同步Servlet
非阻塞Servlet
複製程式碼
在pom中新增依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
複製程式碼
新建Servlet類:
加上註解@Webservlet,配置url對映。
繼承HTTPServlet,這裡我們重寫一個doGet方法。
package com.kim.diveinspringboot.web.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* My Servlet
*/
@WebServlet(urlPatterns = "/my/servlet")
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().println("Hello World.");
}
}
複製程式碼
關聯Servlet的包:加上註解 裡面配置包的路徑@ServletComponentScan(basePackages = "com.kim.diveinspringboot.web.servlet")
package com.kim.diveinspringboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan(basePackages = "com.kim.diveinspringboot.web.servlet")
public class DiveInSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(DiveInSpringBootApplication.class, args);
}
}
複製程式碼
執行:結果沒問題。
非同步非阻塞:
首先我剛開始是不是很懂非同步和同步分別是什麼東西,百度結果:
同步:傳送一個請求,等待返回,然後再傳送下一個請求 非同步:傳送一個請求,不等待返回,隨時可以再傳送下一個請求 同步可以避免出現死鎖,讀髒資料的發生,一般共享某一資源的時候用,如果每個人都有修改許可權,同時修改一個檔案,有可能使一個人讀取另一個人已經刪除的內容,就會出錯,同步就會按順序來修改。 非同步則是可以提高效率了,現在cpu都是雙核,四核,非同步處理的話可以同時做多項工作,當然必須保證是可以併發處理的。 這些都是對的。 同步和非同步最大的區別就在於。一個需要等待,一個不需要等待。 比如廣播,就是一個非同步例子。發起者不關心接收者的狀態。不需要等待接收者的返回資訊 電話,就是一個同步例子。發起者需要等待接收者,接通電話後,通訊才開始。需要等待接收者的返回資訊
在Servlet中實現非同步:
首先要開啟非同步支援,原始碼裡面非同步支援是預設關閉的。
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
AsyncContext asyncContext = req.startAsync();
asyncContext.start(()->{
try{
resp.getWriter().println("Hello World.");
// 觸發完成
asyncContext.complete();
}catch (IOException e){
e.printStackTrace();
}
});
}
複製程式碼
asyncContext.complete();這一句很重要,要觸發完成,不然會一直卡死。
()-> 這個不知道是什麼表示式。。。。
是lambda表示式,不接收引數,執行後面的方法。(Java 8 新特性)
Spring Web MVC應用:
Web MVC檢視:
切換Servlet容器,替換成jetty:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
複製程式碼
tomcat要使用exclusion進行排除,因為他的優先順序要比jetty高,不排除的話,就算jetty已經替換了tomcat還是會先跑tomcat。
替換成Webflux:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
複製程式碼
這裡要注意,要把MyServlet註釋掉,因為會找不到包而報錯。
web不能和webflux共存。
執行。