Spring MVC官方文檔學習筆記(二)之DispatcherServlet

来源:https://www.cnblogs.com/shame11/archive/2023/05/31/17392835.html
-Advertisement-
Play Games

1. 多線程程式在一個核的CPU運行 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/35902537/1685453577663-714d9c16-e8a3-4828-bb86-86dfa10c8e52.png#averageHue=%23f ...


1.DispatcherServlet入門

(1) Spring MVC是以前端控制器模式(即圍繞著一個中央的Servelt, DispatcherServlet)進行設計的,這個DispatcherServlet為請求的處理提供了一個共用的演算法,即它都會將實際的請求處理工作委托給那些可配置的組件進行執行,說白了,DispatcherServlet的作用就是進行統一調度,並控制請求的處理流程,和其他的Servlet一樣,DispatcherServlet需要根據Servlet規範,使用基於Java的配置或在web.xml中進行聲明,與此同時,DispatcherServlet會使用Spring相關配置來發現它在請求映射、視圖解析、異常處理等方面所需要的組件,而實際的工作也會交由這些組件進行執行,下麵列出了註冊DispatcherServlet的一些方式

@Configuration
@ComponentScan("cn.example.springmvc.boke")
public class WebConfig {
}

//使用基於Java的配置,註冊並初始化一個DispatcherServlet
public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        //聲明一個Spring-web容器
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(WebConfig.class);

        //創建並註冊DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(ctx);
        //動態的添加Servlet
        ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcherServlet", servlet);
        registration.setLoadOnStartup(1);
        //指定由DispatcherServlet攔截所有請求(包括靜態資源,但不攔截.jsp)
        registration.addMapping("/");
    }
}

上述是基於Java的配置,我們還可以基於web.xml來配置DispatcherServlet,如下

<web-app ....>
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

(2) 現在DispatcherServlet有了,我們還需要@Controller與@RequestMapping註解,來標註某個訪問應該由誰進行處理,如下,而到此為止,我們就已經完全不需要編寫HttpServlet相關的內容了,可見通過DispatcherServlet幫助我們免去了冗雜的Servlet映射配置

@Controller
public class DemoController {
    @RequestMapping("/demo")
    @ResponseBody
    public String get(HttpServletRequest request) {
        return "aaa";
    }
}

啟動容器,訪問 http://localhost:8080/springmvc/demo, 頁面顯示aaa,說明訪問正常,這便是我們的第一個Spring MVC項目

2.Spring容器的層次結構

(1) 根容器與Servlet子容器

通常情況下,一個web應用中有一個唯一的WebApplicationContext容器就足夠了,但Spring還允許我們配置具有父子關係的根容器和它的Servlet子容器,來形成一個層次結構,如上圖所示,可以很清楚的看到,Spring將表示層相關的組件全部放到了子容器中,而將公共的與基礎服務有關的組件全部放到了根容器中,這樣的話,當我們需要註冊多個DispatcherServlet並共用那些基礎服務組件的時候,不必重覆註冊Service和Dao了,因為每個Servlet子容器都可以從這個根容器中獲取到Service和Dao,這便是層次結構的意義

當然,Spring也支持單容器配置,如開頭中的示例那樣,此外我們可以通過繼承AbstractAnnotationConfigDispatcherServletInitializer來配置父子容器,如下

//配置父子容器,其中容器使用基於註解的配置方式
public class IocInit extends AbstractAnnotationConfigDispatcherServletInitializer {

    //配置 DispatcherServlet 攔截的路徑
    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }

    //設置根容器的配置類
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {RootConfig.class};
    }

    //設置子容器的配置類
    //如果不想形成父子容器,那麼只需將下麵這個getServletConfigClasses()方法返回null即可
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {WebConfig.class};
    }
}

//由於我們採用的是父子容器,因此這就要求我們編寫父子容器的配置文件時,根容器的配置文件(RootConfig)配置非web組件的bean,而子容器的配置文件(WebConfig)配置web組件的bean,同時,也要防止同一組件在不同容器中分別註冊初始化,從而出現兩個相同bean
//根容器配置類,使用excludeFilters排除掉@Controller註解標註的類和@Configuration註解標註的類,這裡之所以要排除掉@Configuration註解標註的類,是為了防止根容器掃描到子容器的配置類WebConfig
@Configuration
@ComponentScan(value = "cn.example.springmvc.boke",
                excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class),
                        @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Configuration.class)
                })
public class RootConfig {
}

//子容器配置類,使用includeFilters指定只掃描由@Controller註解標註的類
@Configuration
@ComponentScan(value = "cn.example.springmvc.boke",
        includeFilters = @ComponentScan.Filter(value = Controller.class, type = FilterType.ANNOTATION))
public class WebConfig {
}

也可以基於web.xml來配置父子容器,如下

<web-app ....>
    <!-- ContextLoaderListener用於配置根容器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 設置根容器的xml配置文件路徑 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springroot.xml</param-value>
    </context-param>

    <!-- DispatcherServlet用於配置子容器 -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 設置子容器的xml配置文件路徑 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springweb.xml</param-value>
        </init-param>
    </servlet>
    
    <!-- 設置 DispatcherServlet 攔截的路徑  -->
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

3.特殊類型的bean

(1) 前面已經提過了,DispatcherServlet會將實際的請求處理過程委托給那些特殊的組件來乾,而它本身起一個統一分配與調度的作用,這些特殊的組件已經由Spring提供了預設的實現,但同時Spring也允許我們自己實現替換它們,下表列出了由 DispatcherServlet檢測到的這些特殊的Bean類型

Bean類型 說明
HandlerMapping 處理器映射器,主要就是將請求路徑(uri)映射到能處理該請求的處理器(handler),DispatcherServlet在接收到請求後,該請求會交由誰來處理?這個匹配查找的工作不是由DispatcherServlet來做的,而是交由HandlerMapping負責的,而至於Handler,我們可以把它理解為在@Controller註解所標註的類中的一個標註了@RequestMapping註解的方法,所謂的匹配本質上就是匹配@RequestMapping註解中所聲明的值罷了。註意:HandlerMapping在查找匹配到對應的Handler後,並不是直接返回這個Handler,而是返回這個Handler的包裝對象HandlerExecutionChain,而這個HandlerExecutionChain其實就是 Handler + 該請求所涉及到的攔截器 所組合而成的一個對象。
兩個主要的HandlerMapping實現類分別是RequestMappingHandlerMapping(標註了@RequestMapping註解的方法)和SimpleUrlHandlerMapping(若在xml中顯式的配置了請求路徑與Controller的對應關係,則會使用該處理器映射器)
HandlerAdapter 幫助 DispatcherServlet 調用映射匹配到的HandlerExecutionChain,換句話說,DispatcherServlet獲得HandlerExecutionChain後,它不會進行調用執行,而是交由HandlerAdapter來調用執行HandlerExecutionChain
HandlerExceptionResolver 解決異常的策略,用於定義在請求映射,參數綁定或方法執行時若發生異常,該怎麼處理
ViewResolver Handler方法執行後,將返回的邏輯視圖名(通常為一個String字元串)解析為真正的視圖(如.jsp 、.html等),併進行視圖渲染,渲染完成後,將視圖返回給DispatcherServlet
LocaleResolver, LocaleContextResolver 用於解析客戶的Locale,實現國際化功能
ThemeResolver 解析你的web應用可使用的主題(theme),主題是一系列靜態資源的集合(比如說css文件,圖片等)
MultipartResolver 專門用於處理文件上傳
FlashMapManager 專門用於保存和管理FlashMap,而這個FlashMap是用來在重定向時傳遞參數的,因為redirect重定向是不能傳遞參數的,此時就可以藉助FlashMap

4.Web MVC配置

(1) 我們可以自定義在上一節中所列出來的那些特殊的bean,DispatcherServlet會檢查它們,如果沒有,那麼它將會使用DispatcherServlet.properties中所列出的預設類型的bean,如下

5.Servlet 配置

(1) 在Servlet環境中,我們可以選擇以編程式的方式或基於web.xml的方式來配置Servlet容器,在本篇開頭的位置也提到過了,如下是一個基於編程式的例子

public class IocInit implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        //創建一個基於xml配置的容器
        XmlWebApplicationContext appContext = new XmlWebApplicationContext();
        appContext.setConfigLocation("classpath:springmvc.xml");

        ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcherServlet", new DispatcherServlet(appContext));
        registration.setLoadOnStartup(1);
        registration.addMapping("/");
    }
}

WebApplicationInitializer是由Spring MVC提供的一個介面,Spring MVC會確保該介面的實現類們會被正確調用以初始化Servlet容器,WebApplicationInitializer有一個抽象基類為AbstractDispatcherServletInitializer,通過繼承該基類可以使得註冊DispatcherServlet更加容易

(2) 除了上面的例子之外,還可以使用基於java的Spring配置,如下,前面也提到過了

public class IocInit extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    //創建一個基於註解配置的容器
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {WebConfig.class};
    }
}

(3) 除此之外,還可以繼承AbstractDispatcherServletInitializer

public class IocInit extends AbstractDispatcherServletInitializer {
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        XmlWebApplicationContext cxt = new XmlWebApplicationContext();
        cxt.setConfigLocation("classpath:springmvc.xml");
        return cxt;
    }

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }
}

上面列出了常見的3種創建ioc容器的方式,我們可以根據自己的需要來進行選擇

(4) AbstractDispatcherServletInitializer還提供了一種便捷的方式來創建Filter實例,並且這些Filter實例會被自動映射到DispatcherServlet上,如下

public class IocInit extends AbstractDispatcherServletInitializer {

    //...
    
    //這些Filter會被自動映射到DispatcherServlet上,並且會根據它們的類型來為其添加一個預設名稱
    @Override
    protected Filter[] getServletFilters() {
        return new Filter[] {
                new HiddenHttpMethodFilter(), new CharacterEncodingFilter() };
    }
}

此外,如果我們希望需要進一步的定製DispatcherServlet,我們可以重寫createDispatcherServlet方法

6.請求處理

(1) DispatcherServlet按照如下的方式來處理請求:

  • 搜索WebApplicationContext並將其作為一個屬性綁定到請求中,這樣在請求的後續處理過程中我們就可以直接從請求中拿到ioc容器,如下
@Controller
public class DemoController {
    @RequestMapping("/demo")
    @ResponseBody
    public String get(HttpServletRequest httpServletRequest) {
        //從請求中獲取到WebApplicationContext,這個ioc容器被綁定到了請求的DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE屬性上
        WebApplicationContext ctx = (WebApplicationContext)httpServletRequest.getAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE);
        Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println);
        return "aaa";
    }
}
  • Locale解析器也被綁定到了請求上,以便後續處理流程中進行使用

  • Theme解析器也被綁定到了請求上,以便後續處理流程中進行使用

  • 如果我們指定了multipart文件解析器,那麼Spring會檢查請求中是否含有multipart文件,如果有,那麼該請求會被包裹在一個MultipartHttpServletRequest中,以便後續處理流程中進行進一步處理

  • 針對請求搜索恰當的handler,如果搜索到的話,與該handler相關的執行鏈(HandlerExecutionChain)將會被執行,以準備渲染模型(model)

  • 如果有模型返回,那麼視圖(view)就會被渲染,否則,如果沒有模型返回,那麼視圖就不會被渲染

(2) 在WebApplicationContext中的HandlerExceptionResolver類型的bean將被用來解決請求處理過程中拋出的異常,這些異常解析器允許自定義處理異常的邏輯

(3) 我們可以在web.xml中的標簽使用標簽來添加Servlet初始化參數,這樣就能達到定製DispatcherServlet的目的,下麵列出了DispatcherServlet常見的初始化參數

參數 說明
contextClass 設置web容器,該容器必須是ConfigurableWebApplicationContext的實現類,預設為XmlWebApplicationContext
contextConfigLocation 該參數值將會被傳遞至由上面contextClass指定的容器,通常用於指明配置文件(xml文件,@Configuration註解標註的類)的路徑,容器會到指定位置載入配置文件
namespace 容器的命名空間,預設為[servlet-name]-servlet
throwExceptionIfNoHandlerFound 決定當一個請求沒有找到其對應的handler時,是否會拋出NoHandlerFoundException異常,若設置為true,則表示拋出異常,然後我們就可以用HandlerExceptionResolver來捕獲該異常,並像處理其他異常一樣進行該處理。在預設情況下,該值被設置為false,因此在預設情況下,如果一個請求沒有找到其對應的handler,那麼DispatcherServlet會將響應狀態碼設置為404(NOT_FOUND)而不會引發異常,因此我們會在頁面上看到一個 "404 - 未找到" 頁面,最後註意,如果defaultServletHandling也被配置了,那麼這些不正常的請求會被轉發到defaultServlet進行處理,且永遠不會出現404

具體的配置例子如下

<web-app ....>

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置容器,容器需要實現ConfigurableWebApplicationContext介面,此處我們選擇了XmlWebApplicationContext,這也是Spring的預設配置 -->
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.XmlWebApplicationContext</param-value>
        </init-param>

        <!-- 因為我們上面選用的是XmlWebApplicationContext,一個基於xml配置的容器,因此通過contextConfigLocation屬性來設置容器的xml配置文件路徑 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springweb.xml</param-value>
        </init-param>

        <!-- 如下是配置一個基於註解的容器 -->
<!--        <init-param>-->
<!--            <param-name>contextClass</param-name>-->
<!--            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>-->
<!--        </init-param>-->
        <!-- 因為是基於註解的容器,因此通過contextConfigLocation屬性來設置Configuration配置類的路徑 -->
<!--        <init-param>-->
<!--            <param-name>contextConfigLocation</param-name>-->
<!--            <param-value>cn.example.springmvc.boke.config.Config</param-value>-->
<!--        </init-param>-->

        <!-- 設置WebApplicationContext的命名空間 -->
        <init-param>
            <param-name>namespace</param-name>
            <param-value>app</param-value>
        </init-param>

        <!-- 註意,單單將這個值設置為true,並不會生效(即不會拋出NoHandlerFoundException異常),原因是Spring會預設加上ResourceHttpRequestHandler這個handler來進行處理,也就不會出現no handler的情況了,因此我們還需要配置spring.resources.add-mappings=false,這樣在發生no handler時才會拋出NoHandlerFoundException異常 -->
        <init-param>
            <param-name>throwExceptionIfNoHandlerFound</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>

    <!-- 設置 DispatcherServlet 攔截的路徑  -->
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

7.攔截器

(1) 攔截器必須實現HandlerInterceptor介面,該介面提供了3個方法,分別為

  • preHandle(..): 在handler執行之前執行

  • postHandle(..): 在handler執行之後執行

  • afterCompletion(..): 在整個請求完成後執行

preHandle方法返回一個boolean值,通過該方法我們可以決定是繼續還是中斷執行鏈的執行,若返回true,則執行鏈繼續執行,若返回false,則DispatcherServlet會認為攔截器本身已經處理了該請求,因此會中斷執行鏈中其他的攔截器以及handler的執行

postHandle方法在有@ResponseBody和ResponseEntity的方法中用處不大,因為這種方法在postHandle方法執行前已經在寫入response了,等待postHandle方法執行時已經太遲了,而針對這種情況,我們可以使用ResponseBodyAdvice

8.異常

(1) 如果在請求映射處理過程中發生異常,DispatcherServlet會委托一個由HandlerExceptionResolver構成的異常處理鏈來處理這個異常,下麵列出一些可用的HandlerExceptionResolver實現類

HandlerExceptionResolver 說明
SimpleMappingExceptionResolver 提供異常類名稱與異常視圖名稱之間的一個映射,即針對不同類型的異常響應不同的錯誤視圖
DefaultHandlerExceptionResolver 解析由Spring MVC引發的標準異常,並將它們映射成對應的HTTP狀態碼,它是作為“預設”使用的,如果其他HandlerExceptionResolver不能處理某些異常,最後會使用DefaultHandlerExceptionResolver來統一處理
ResponseStatusExceptionResolver 解析被@ResponseStatus註解標註的異常,並根據註解中的值將異常映射到對應的HTTP狀態碼
ExceptionHandlerExceptionResolver 通過調用@ControllerAdvice類或@Controller類中合適的@ExceptionHandler方法來解析異常

(2) 我們可以在容器中配置多個HandlerExceptionResolver類型的bean並根據需要設置它們的order屬性來形成一個異常處理器鏈,其中order屬性值越高,它在異常處理器鏈中的位置就越靠後,通常情況下,HandlerExceptionResolver返回

  • 一個指向錯誤視圖的ModelAndView

  • 若異常在處理器中被處理,返回一個空的ModelAndView

  • 若異常未被解決,則返回null,以便讓後續的處理器嘗試解決,如果到最後異常仍未解決,則允許將異常冒泡到Servlet容器中

使用MVC Config(通過@EnableWebMvc註解)後,會自動的向容器中添加Spring MVC異常,由@ResponseStatus註解標註的異常等異常的處理器,我們可以對它們進行替換

(3) 如果一個異常沒有被任何HandlerExceptionResolver處理或者請求的http響應被設置為錯誤狀態(即4xx,5xx),那麼Servlet容器使用HTML來渲染一個預設的錯誤頁面,而為了自定義容器的預設錯誤頁面,我們可以在web.xml中配置錯誤頁面映射url,如下

<error-page>
    <location>/error</location>
</error-page>

當配置好錯誤頁面映射url後,如果此時有一個異常沒有被任何HandlerExceptionResolver處理或者請求的http響應被設置為錯誤狀態,那麼Servlet容器將會請求我們所配置的這個url,此時,我們就可以返回一個自定義的錯誤視圖或像下麵這樣直接返回一個字元串

@RequestMapping("/error")
@ResponseBody
public String error() {
    return "error";
}

9. view,locale,theme和logging這四節的內容略過,如果有需要可查看官方文檔

10. Multipart解析器

(1) org.springframework.web.multipart包中的MultipartResolver可用於解析multipart類型(例如:文件上傳)的請求,為了使用Multipart解析器,我們需要配置一個MultipartResolver類型的bean,並且這個bean的名稱必須是multipartResolver,配置好之後,DispatcherServlet會檢測到它並將其應用於後續的請求,當我們接收到一個類型為multipart/form-data的post請求時,Multipart解析器會解析請求內容並將當前這個HttpServletRequest包裝成MultipartHttpServletRequest以便訪問解析的內容,Spring MVC已為我們提供了兩個MultipartResolver的實現類,如下

  • CommonsMultipartResolver:基於Apache Commons FileUpload的MultipartResolver實現類,為了使用它,需要添加commons-fileupload依賴

  • StandardServletMultipartResolver:基於Servlet 3.0 multipart請求解析的MultipartResolver實現類,為了使用它,我們需要在<web.xml/>或Servlet registration中進行一些配置:

<!-- 在web.xml的<servlet/>標簽中添加<multipart-config/>標簽,配置上傳文件的大小等信息 -->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <multipart-config>
        <location>/</location>
        <max-file-size>2097152</max-file-size>
        <max-request-size>419304</max-request-size>
    </multipart-config>
</servlet>

也可在Servlet registration中進行配置

public class IocInit extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {RootConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {WebConfig.class};
    }

    //使用ServletRegistration配置上傳文件大小等信息
    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        registration.setMultipartConfig(new MultipartConfigElement("/", 2097152, 419304, 0));
    }
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ### 外觀式定義 為子系統中的一組介面提供一個一致的界面,Facade 模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。 #### 界面 在這裡提到的界面,主要指的是從一個組件外部來看這個組件,能夠看到什麼,這就是這個組件的界面,也就是所說的外觀。 #### 介面 在這裡提到的介面,主 ...
  • # 前言 本文主要講述**工廠模式**,文中使用通俗易懂的案例,使你更好的學習本章知識點並理解原理,做到有道無術。 # 一.什麼是工廠模式 工廠模式是23種設計模式中**創建型模式**的一種,它是一個最簡單的對象創建管理方式,根據調用方傳遞的類型來創建對象並返回。封裝了對象創建的過程,降低了程式模塊 ...
  • ### 解釋器模式(Interpreter Pattern) #### 一、定義 解釋器模式(Interpreter Pattern)提供了評估語言的語法或表達式的方式,它屬於行為型模式。這種模式實現了一個表達式介面,該介面解釋一個特定的上下文。這種模式被用在 SQL 解析、符號處理引擎等。 給定一 ...
  • 在Java中,序列化(Serialization)是指將對象的狀態轉換為位元組流的過程,以便將其保存到文件、在網路中傳輸或持久化到資料庫中。而反序列化(Deserialization)則是將位元組流轉換回對象的過程,恢復對象的狀態。 序列化和反序列化主要用於以下場景: 1. 對象持久化:通過序列化,可以 ...
  • > 內容摘自我的學習網站:topjavaer.cn Redis連環40問,絕對夠全! ## Redis是什麼? Redis(`Remote Dictionary Server`)是一個使用 C 語言編寫的,高性能非關係型的鍵值對資料庫。與傳統資料庫不同的是,Redis 的數據是存在記憶體中的,所以讀寫 ...
  • > 本文首發於公眾號:Hunter後端 > 原文鏈接:[Python連接es筆記四之創建和刪除操作](https://mp.weixin.qq.com/s/ZCe0JT9TDEiZI7M5dxC9qA) 這一篇筆記介紹一下索引和數據的創建和刪除。 其實對於索引來說,如果可以接觸到 kibana 的話 ...
  • > 源碼都背下來了,你給我看這 **我是 javapub,一名 `Markdown` 程式員從👨‍💻,八股文種子選手。** **面試官: 你好,我看到你的簡歷上寫著你熟悉 Java 中的 "synchronized" 關鍵字。你能給我講講它的作用嗎?** **候選人:** 當然,"synchro ...
  • # 1. Netty總體結構 ## 1.1 Netty簡介 ​ Netty是一款用於創建高性能網路應用程式的高級框架。它的基於 Java NIO 的非同步的和事件驅動的實現,保證了高負載下應用程式性能的最大化和可伸縮性。 ​ 其次,Netty 也包含了一組**設計模式**,將應用程式邏輯從網路層解耦, ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...