最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaWeb?中的?Filter組件詳解

 更新時(shí)間:2025年11月27日 14:41:44   作者:總會(huì)落葉  
本文詳細(xì)介紹了JavaWeb中的Filter組件,包括其基本概念、工作原理、核心接口和類、配置方式以及常見(jiàn)應(yīng)用示例,Filter可以實(shí)現(xiàn)請(qǐng)求預(yù)處理、響應(yīng)后處理、鏈?zhǔn)教幚淼裙δ?通過(guò)配置文件或注解進(jìn)行設(shè)置,適用于字符編碼、身份認(rèn)證、日志記錄等多種場(chǎng)景,感興趣的朋友一起學(xué)習(xí)吧

JavaWeb 中的 Filter 詳解

1. Filter 基本概念

1.1 什么是 Filter

Filter(過(guò)濾器)是 JavaWeb 中的一種組件,用于在請(qǐng)求到達(dá) Servlet 之前或響應(yīng)發(fā)送到客戶端之前對(duì)請(qǐng)求和響應(yīng)進(jìn)行預(yù)處理和后處理。

1.2 Filter 的作用

  • 請(qǐng)求預(yù)處理:在請(qǐng)求到達(dá) Servlet 之前進(jìn)行處理
  • 響應(yīng)后處理:在響應(yīng)發(fā)送到客戶端之前進(jìn)行處理
  • 鏈?zhǔn)教幚?/strong>:多個(gè) Filter 可以形成處理鏈
  • 動(dòng)態(tài)攔截:根據(jù)條件決定是否繼續(xù)執(zhí)行

2. Filter 的工作原理

2.1 Filter 生命周期

public class MyFilter implements Filter {
    // 1. 初始化方法 - 容器啟動(dòng)時(shí)調(diào)用
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter 初始化");
    }
    // 2. 過(guò)濾方法 - 每次請(qǐng)求時(shí)調(diào)用
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        // 前置處理
        System.out.println("請(qǐng)求到達(dá) Filter");
        // 傳遞給下一個(gè) Filter 或 Servlet
        chain.doFilter(request, response);
        // 后置處理
        System.out.println("響應(yīng)經(jīng)過(guò) Filter");
    }
    // 3. 銷毀方法 - 容器關(guān)閉時(shí)調(diào)用
    @Override
    public void destroy() {
        System.out.println("Filter 銷毀");
    }
}

2.2 Filter 執(zhí)行流程

客戶端請(qǐng)求 → Filter1 → Filter2 → ... → Servlet → Filter2 → Filter1 → 客戶端響應(yīng)

3. Filter 的核心接口和類

3.1 Filter 接口

public interface Filter {
    void init(FilterConfig filterConfig);
    void doFilter(ServletRequest request, ServletResponse response, 
                 FilterChain chain);
    void destroy();
}

3.2 FilterConfig 接口

public interface FilterConfig {
    String getFilterName();
    ServletContext getServletContext();
    String getInitParameter(String name);
    Enumeration<String> getInitParameterNames();
}

3.3 FilterChain 接口

public interface FilterChain {
    void doFilter(ServletRequest request, ServletResponse response);
}

4. Filter 的配置方式

4.1 注解配置(推薦)

@WebFilter(
    filterName = "myFilter",
    urlPatterns = {"/*"},
    initParams = {
        @WebInitParam(name = "encoding", value = "UTF-8"),
        @WebInitParam(name = "excludePaths", value = "/static/*")
    }
)
public class MyFilter implements Filter {
    // Filter 實(shí)現(xiàn)
}

4.2 web.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         version="3.1">
    <filter>
        <filter-name>myFilter</filter-name>
        <filter-class>com.example.MyFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>myFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
</web-app>

5. 常用 Filter 實(shí)現(xiàn)示例

5.1 字符編碼過(guò)濾器

@WebFilter(
    urlPatterns = "/*",
    initParams = @WebInitParam(name = "encoding", value = "UTF-8")
)
public class CharacterEncodingFilter implements Filter {
    private String encoding = "UTF-8";
    @Override
    public void init(FilterConfig filterConfig) {
        String encodingParam = filterConfig.getInitParameter("encoding");
        if (encodingParam != null && !encodingParam.isEmpty()) {
            this.encoding = encodingParam;
        }
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        // 設(shè)置請(qǐng)求編碼
        request.setCharacterEncoding(encoding);
        // 設(shè)置響應(yīng)編碼
        response.setCharacterEncoding(encoding);
        response.setContentType("text/html;charset=" + encoding);
        System.out.println("設(shè)置字符編碼: " + encoding);
        chain.doFilter(request, response);
    }
    @Override
    public void destroy() {
        // 清理資源
    }
}

5.2 身份認(rèn)證過(guò)濾器

@WebFilter(urlPatterns = {"/admin/*", "/user/*"})
public class AuthenticationFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        HttpSession session = httpRequest.getSession(false);
        // 檢查用戶是否登錄
        if (session == null || session.getAttribute("user") == null) {
            // 未登錄,重定向到登錄頁(yè)面
            httpResponse.sendRedirect(httpRequest.getContextPath() + "/login");
            return;
        }
        // 檢查用戶權(quán)限
        User user = (User) session.getAttribute("user");
        String requestURI = httpRequest.getRequestURI();
        if (requestURI.contains("/admin/") && !user.isAdmin()) {
            httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "權(quán)限不足");
            return;
        }
        System.out.println("用戶 " + user.getUsername() + " 訪問(wèn): " + requestURI);
        chain.doFilter(request, response);
    }
}

5.3 日志記錄過(guò)濾器

@WebFilter("/*")
public class LoggingFilter implements Filter {
    private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        long startTime = System.currentTimeMillis();
        // 記錄請(qǐng)求信息
        String clientIP = getClientIP(httpRequest);
        String requestURI = httpRequest.getRequestURI();
        String method = httpRequest.getMethod();
        logger.info("請(qǐng)求開(kāi)始: {} {} from {}", method, requestURI, clientIP);
        try {
            chain.doFilter(request, response);
        } finally {
            // 記錄響應(yīng)信息
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            int status = httpResponse.getStatus();
            logger.info("請(qǐng)求完成: {} {} - 狀態(tài): {} - 耗時(shí): {}ms", 
                       method, requestURI, status, duration);
        }
    }
    private String getClientIP(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty()) {
            return xForwardedFor.split(",")[0];
        }
        return request.getRemoteAddr();
    }
}

5.4 跨域過(guò)濾器 (CORS)

@WebFilter("/*")
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        // 設(shè)置 CORS 頭
        httpResponse.setHeader("Access-Control-Allow-Origin", "*");
        httpResponse.setHeader("Access-Control-Allow-Methods", 
                             "GET, POST, PUT, DELETE, OPTIONS");
        httpResponse.setHeader("Access-Control-Allow-Headers", 
                             "Content-Type, Authorization, X-Requested-With");
        httpResponse.setHeader("Access-Control-Max-Age", "3600");
        // 處理預(yù)檢請(qǐng)求
        if ("OPTIONS".equalsIgnoreCase(httpRequest.getMethod())) {
            httpResponse.setStatus(HttpServletResponse.SC_OK);
            return;
        }
        chain.doFilter(request, response);
    }
}

5.5 XSS 防護(hù)過(guò)濾器

@WebFilter("/*")
public class XSSFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        // 包裝請(qǐng)求對(duì)象,對(duì)參數(shù)進(jìn)行 XSS 過(guò)濾
        XSSRequestWrapper wrappedRequest = new XSSRequestWrapper(
            (HttpServletRequest) request);
        chain.doFilter(wrappedRequest, response);
    }
}
// XSS 請(qǐng)求包裝器
class XSSRequestWrapper extends HttpServletRequestWrapper {
    public XSSRequestWrapper(HttpServletRequest request) {
        super(request);
    }
    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        return cleanXSS(value);
    }
    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if (values == null) return null;
        String[] cleanedValues = new String[values.length];
        for (int i = 0; i < values.length; i++) {
            cleanedValues[i] = cleanXSS(values[i]);
        }
        return cleanedValues;
    }
    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        return cleanXSS(value);
    }
    private String cleanXSS(String value) {
        if (value == null) return null;
        // 簡(jiǎn)單的 XSS 過(guò)濾
        return value.replaceAll("<", "<")
                   .replaceAll(">", ">")
                   .replaceAll("\"", "&quot;")
                   .replaceAll("'", "&#x27;")
                   .replaceAll("/", "&#x2F;")
                   .replaceAll("\\(", "&#40;")
                   .replaceAll("\\)", "&#41;")
                   .replaceAll("script", "scr_ipt")
                   .replaceAll("javascript", "java_script");
    }
}

6. Filter 的配置參數(shù)詳解

6.1 URL 模式匹配

@WebFilter(
    urlPatterns = {
        "*.html",           // 所有 HTML 文件
        "/api/*",           // /api 路徑下的所有請(qǐng)求
        "/admin/*",         // /admin 路徑下的所有請(qǐng)求
        "/*"                // 所有請(qǐng)求
    }
)

6.2 Dispatcher 類型

@WebFilter(
    urlPatterns = "/*",
    dispatcherTypes = {
        DispatcherType.REQUEST,     // 直接請(qǐng)求
        DispatcherType.FORWARD,     // 轉(zhuǎn)發(fā)請(qǐng)求
        DispatcherType.INCLUDE,     // 包含請(qǐng)求
        DispatcherType.ERROR,       // 錯(cuò)誤處理
        DispatcherType.ASYNC        // 異步請(qǐng)求
    }
)

6.3 初始化參數(shù)

@WebFilter(
    urlPatterns = "/*",
    initParams = {
        @WebInitParam(name = "excludePaths", value = "/static/,/public/"),
        @WebInitParam(name = "maxFileSize", value = "10485760"), // 10MB
        @WebInitParam(name = "allowedTypes", value = "jpg,png,pdf")
    }
)

7. Filter 的執(zhí)行順序

7.1 執(zhí)行順序規(guī)則

  1. web.xml 配置順序:按照配置文件中定義的順序執(zhí)行
  2. 注解配置順序:使用 @WebFilterfilterName 字母順序
  3. 混合配置:web.xml 優(yōu)先于注解

7.2 控制執(zhí)行順序的方法

// 方法1: 使用 web.xml 明確指定順序
<filter-mapping>
    <filter-name>filter1</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>filter2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
// 方法2: 使用 @Order 注解(需要框架支持)
@Order(1)
@WebFilter("/*")
public class FirstFilter implements Filter { }
@Order(2)
@WebFilter("/*")
public class SecondFilter implements Filter { }

8. Filter 的高級(jí)用法

8.1 條件過(guò)濾

@WebFilter("/*")
public class ConditionalFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestURI = httpRequest.getRequestURI();
        // 排除靜態(tài)資源
        if (requestURI.startsWith("/static/") || 
            requestURI.endsWith(".css") || 
            requestURI.endsWith(".js")) {
            chain.doFilter(request, response);
            return;
        }
        // 對(duì)動(dòng)態(tài)請(qǐng)求進(jìn)行特殊處理
        System.out.println("處理動(dòng)態(tài)請(qǐng)求: " + requestURI);
        // 添加自定義請(qǐng)求屬性
        httpRequest.setAttribute("processingTime", System.currentTimeMillis());
        chain.doFilter(request, response);
        // 后處理
        Long startTime = (Long) httpRequest.getAttribute("processingTime");
        if (startTime != null) {
            long duration = System.currentTimeMillis() - startTime;
            System.out.println("請(qǐng)求處理耗時(shí): " + duration + "ms");
        }
    }
}

8.2 響應(yīng)包裝器

@WebFilter("/*")
public class CompressionFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String acceptEncoding = httpRequest.getHeader("Accept-Encoding");
        if (acceptEncoding != null && acceptEncoding.contains("gzip")) {
            // 使用 GZIP 壓縮響應(yīng)
            CompressionResponseWrapper wrappedResponse = 
                new CompressionResponseWrapper(httpResponse);
            chain.doFilter(request, wrappedResponse);
            // 完成壓縮并發(fā)送響應(yīng)
            wrappedResponse.finish();
        } else {
            chain.doFilter(request, response);
        }
    }
}
// 壓縮響應(yīng)包裝器
class CompressionResponseWrapper extends HttpServletResponseWrapper {
    private GZIPServletOutputStream gzipStream;
    private PrintWriter printWriter;
    public CompressionResponseWrapper(HttpServletResponse response) 
        throws IOException {
        super(response);
    }
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        if (printWriter != null) {
            throw new IllegalStateException("getWriter() has already been called");
        }
        if (gzipStream == null) {
            gzipStream = new GZIPServletOutputStream(super.getOutputStream());
        }
        return gzipStream;
    }
    @Override
    public PrintWriter getWriter() throws IOException {
        if (gzipStream != null) {
            throw new IllegalStateException("getOutputStream() has already been called");
        }
        if (printWriter == null) {
            gzipStream = new GZIPServletOutputStream(super.getOutputStream());
            printWriter = new PrintWriter(new OutputStreamWriter(gzipStream, 
                getCharacterEncoding()));
        }
        return printWriter;
    }
    public void finish() throws IOException {
        if (printWriter != null) {
            printWriter.close();
        }
        if (gzipStream != null) {
            gzipStream.finish();
        }
    }
}

9. Filter 的最佳實(shí)踐

9.1 性能考慮

@WebFilter("/*")
public class PerformanceFilter implements Filter {
    private boolean enableProfiling;
    @Override
    public void init(FilterConfig filterConfig) {
        // 從配置中讀取性能開(kāi)關(guān)
        String profiling = filterConfig.getInitParameter("enableProfiling");
        this.enableProfiling = "true".equalsIgnoreCase(profiling);
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        if (!enableProfiling) {
            chain.doFilter(request, response);
            return;
        }
        long startTime = System.nanoTime();
        try {
            chain.doFilter(request, response);
        } finally {
            long endTime = System.nanoTime();
            long duration = (endTime - startTime) / 1_000_000; // 轉(zhuǎn)換為毫秒
            if (duration > 1000) { // 超過(guò)1秒的記錄警告
                System.err.println("慢請(qǐng)求: " + duration + "ms");
            }
        }
    }
}

9.2 異常處理

@WebFilter("/*")
public class ExceptionHandlingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        try {
            chain.doFilter(request, response);
        } catch (Exception e) {
            // 統(tǒng)一異常處理
            handleException(e, request, response);
        }
    }
    private void handleException(Exception e, ServletRequest request, 
                               ServletResponse response) throws IOException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        // 記錄異常日志
        System.err.println("處理請(qǐng)求時(shí)發(fā)生異常: " + httpRequest.getRequestURI());
        e.printStackTrace();
        // 返回統(tǒng)一的錯(cuò)誤響應(yīng)
        httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        httpResponse.setContentType("application/json");
        String errorJson = "{\"error\": \"服務(wù)器內(nèi)部錯(cuò)誤\", \"code\": 500}";
        httpResponse.getWriter().write(errorJson);
    }
}

10. Filter 的測(cè)試

10.1 單元測(cè)試示例

public class AuthenticationFilterTest {
    @Test
    public void testDoFilter_AuthenticatedUser() throws Exception {
        // 創(chuàng)建模擬對(duì)象
        HttpServletRequest mockRequest = mock(HttpServletRequest.class);
        HttpServletResponse mockResponse = mock(HttpServletResponse.class);
        FilterChain mockChain = mock(FilterChain.class);
        HttpSession mockSession = mock(HttpSession.class);
        // 設(shè)置模擬行為
        when(mockRequest.getSession(false)).thenReturn(mockSession);
        when(mockSession.getAttribute("user")).thenReturn(new User("testUser"));
        when(mockRequest.getRequestURI()).thenReturn("/user/profile");
        // 執(zhí)行測(cè)試
        AuthenticationFilter filter = new AuthenticationFilter();
        filter.doFilter(mockRequest, mockResponse, mockChain);
        // 驗(yàn)證結(jié)果
        verify(mockChain).doFilter(mockRequest, mockResponse);
    }
    @Test
    public void testDoFilter_UnauthenticatedUser() throws Exception {
        // 創(chuàng)建模擬對(duì)象
        HttpServletRequest mockRequest = mock(HttpServletRequest.class);
        HttpServletResponse mockResponse = mock(HttpServletResponse.class);
        FilterChain mockChain = mock(FilterChain.class);
        // 設(shè)置模擬行為
        when(mockRequest.getSession(false)).thenReturn(null);
        when(mockRequest.getContextPath()).thenReturn("/myapp");
        // 執(zhí)行測(cè)試
        AuthenticationFilter filter = new AuthenticationFilter();
        filter.doFilter(mockRequest, mockResponse, mockChain);
        // 驗(yàn)證重定向
        verify(mockResponse).sendRedirect("/myapp/login");
        verify(mockChain, never()).doFilter(mockRequest, mockResponse);
    }
}

總結(jié)

Filter 是 JavaWeb 中非常重要的組件,它提供了以下核心功能:

  1. 請(qǐng)求預(yù)處理響應(yīng)后處理
  2. 鏈?zhǔn)教幚?/strong>機(jī)制
  3. 靈活的配置方式
  4. 強(qiáng)大的攔截能力

通過(guò)合理使用 Filter,可以實(shí)現(xiàn):

  • 統(tǒng)一的字符編碼處理
  • 身份認(rèn)證和授權(quán)
  • 請(qǐng)求日志記錄
  • 性能監(jiān)控
  • 安全防護(hù)
  • 跨域處理
  • 數(shù)據(jù)壓縮等

Filter 的設(shè)計(jì)遵循了 AOP(面向切面編程)的思想,使得橫切關(guān)注點(diǎn)能夠與業(yè)務(wù)邏輯分離,提高了代碼的可維護(hù)性和復(fù)用性。

到此這篇關(guān)于JavaWeb 中的 Filter 詳解的文章就介紹到這了,更多相關(guān)javaweb filter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot?AOP中JoinPoint的使用方式和通知切點(diǎn)表達(dá)式

    SpringBoot?AOP中JoinPoint的使用方式和通知切點(diǎn)表達(dá)式

    這篇文章主要介紹了SpringBoot?AOP中JoinPoint的使用方式和通知切點(diǎn)表達(dá)式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • springboot2如何集成ElasticSearch6.4.3

    springboot2如何集成ElasticSearch6.4.3

    這篇文章主要介紹了springboot2如何集成ElasticSearch6.4.3問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java實(shí)現(xiàn)PDF文檔自動(dòng)化比較的教程解析

    Java實(shí)現(xiàn)PDF文檔自動(dòng)化比較的教程解析

    在日常工作中,我們經(jīng)常需要處理大量的 PDF 文檔,本文將深入探討如何利用 Java 技術(shù),結(jié)合強(qiáng)大的 Spire.PDF for Java 庫(kù),實(shí)現(xiàn) PDF 文檔的自動(dòng)化比較,感興趣的可以了解下
    2025-11-11
  • Hibernate緩存詳解

    Hibernate緩存詳解

    本文主要介紹了Hibernate緩存的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • VS?Code中運(yùn)行Java?SpringBoot的項(xiàng)目詳細(xì)步驟

    VS?Code中運(yùn)行Java?SpringBoot的項(xiàng)目詳細(xì)步驟

    這篇文章主要介紹了VS?Code中運(yùn)行Java?SpringBoot項(xiàng)目的相關(guān)資料,文中涵蓋了安裝必要的擴(kuò)展、配置環(huán)境、創(chuàng)建或?qū)腠?xiàng)目、配置調(diào)試環(huán)境、運(yùn)行和調(diào)試項(xiàng)目、使用Spring?Boot?Actuator以及配置任務(wù)自動(dòng)化等步驟,需要的朋友可以參考下
    2024-12-12
  • Java詳解entity轉(zhuǎn)換到vo過(guò)程

    Java詳解entity轉(zhuǎn)換到vo過(guò)程

    這篇文章將用實(shí)例來(lái)和大家介紹一下entity轉(zhuǎn)換到vo的方法過(guò)程。文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下
    2022-06-06
  • SpringBoot實(shí)現(xiàn)熱啟動(dòng)的三種方案

    SpringBoot實(shí)現(xiàn)熱啟動(dòng)的三種方案

    在SpringBoot項(xiàng)目中,傳統(tǒng)開(kāi)發(fā)模式下每次修改代碼都需要手動(dòng)重啟應(yīng)用,這會(huì)觸發(fā)完整的 JVM 關(guān)閉與重新加載過(guò)程,對(duì)于大型項(xiàng)目,這個(gè)流程耗時(shí) 10–30 秒,所以本文給大家介紹了SpringBoot實(shí)現(xiàn)熱啟動(dòng)的三種方案,需要的朋友可以參考下
    2025-11-11
  • SpringSecurity實(shí)現(xiàn)訪問(wèn)控制url匹配

    SpringSecurity實(shí)現(xiàn)訪問(wèn)控制url匹配

    本文主要介紹了SpringSecurity實(shí)現(xiàn)訪問(wèn)控制url匹配,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • java常用工具類 數(shù)字工具類

    java常用工具類 數(shù)字工具類

    這篇文章主要為大家詳細(xì)介紹了java常用工具類中的數(shù)字工具類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • Java集合框架實(shí)戰(zhàn)HashMap與HashSet的使用案例

    Java集合框架實(shí)戰(zhàn)HashMap與HashSet的使用案例

    本文通過(guò)兩個(gè)案例詳細(xì)介紹了HashMap和HashSet在Java中的應(yīng)用,通過(guò)這些案例,我們學(xué)習(xí)了如何選擇合適的集合類型、重寫(xiě)equals和hashCode方法、利用泛型和并發(fā)集合等最佳實(shí)踐,感興趣的朋友跟隨小編一起看看吧
    2025-11-11

最新評(píng)論

平武县| 大城县| 揭阳市| 望奎县| 拉孜县| 和平县| 长葛市| 秭归县| 慈利县| 安吉县| 九江县| 南召县| 科技| 祁门县| 柞水县| 镇赉县| 乐清市| 商城县| 大理市| 嵩明县| 哈巴河县| 哈巴河县| 东乡| 青铜峡市| 宕昌县| 泰来县| 波密县| 泾阳县| 米林县| 基隆市| 德江县| 无为县| 栾城县| 黑水县| 饶阳县| 乐陵市| 舒兰市| 金溪县| 台江县| 高邮市| 滁州市|