SpringWebmvc和SpringWebflux

SpringWebmvc和SpringWebflux

webmvc和webflux作为spring framework的两个重要模块,代表了两个IO模型,阻塞式和非阻塞式。SpringWebflux是SpringFramework5.0添加的新功能。

​ webmvc是基于web servlet的阻塞式模型(一般称为oio),一个请求到达服务器后会单独分配一个线程去处理请求,如果请求包含IO操作,线程在IO操作结束之前一直处于阻塞等待状态,这样线程在等待IO操作结束的时间就浪费了。Web on Servlet Stack

​ webflux是基于web reactor的非阻塞模型(一般称为nio),webflx是反应式编程,反应式编程是关于非阻塞应用程序,它们是异步和事件驱动的,需要少量线程垂直扩展(即在JVM内)而不是水平扩展(即通过集群)。反应式应用的一个关键方面是背压的概念,这是一种确保生产者不会压倒消费者的机制。例如,当HTTP连接太慢时,在从数据库扩展到HTTP响应的反应组件的管道中,数据存储库也可以减速或完全停止,直到网络容量释放。比如,当请求到达服务器后也会分配一个线程去处理请求,如果请求包含IO操作,线程在IO操作结束之前不再是处于阻塞等待状态,而是去处理其他事情,等到IO操作结束之后,再通知(得益于系统的机制)线程继续处理请求。它也自持函数式编程来定义路由端点处理请求,通过使用 CompletableFuturefrom Java 8通过lambda表达式组成后续操作。Web on Reactive Stack

总结: struts2,springmvc等都是基于Servlet API与Servlet容器基础之上运行的,在Servlet3.1之后才有了异步非阻塞的支持。而WebFlux是一个典型非阻塞异步的框架,它的核心是基于Reactor的相关API实现的。相对于传统的web框架来说,它可以运行在诸如Netty,Undertow及支持Servlet3.1的容器上,因此它的运行环境的可选择行要比传统web框架多的多。SpringMVC采用命令式编程方,而WebFlux则是基于异步响应式编程。 SpringWebFlux并不会提高程序的运行速度(相对于SpringMVC来说),而是在有限的资源下提高系统的伸缩性,相对于提高程序的高并发。

img

1.依赖关系

//spring mvc 依赖
<dependencies>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
</dependencies>
 
//spring webflux 依赖
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
 
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
</dependencies>

​ springboot-webflux

img

springboot-web

img

2.服务器配置

webmvc使用实现WebMvcConfigurer接口,详细SpringBoot---WebMvcConfigurer详解_zhangpower1993的博客-CSDN博客_webmvcconfigurer

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
@Configuration
@EnableWebMvc        //使用注解@EnableWebMvc
public class MyWebConnfig implements WebMvcConfigurer {
//    addInterceptors:拦截器
//    addViewControllers:页面跳转
//    addResourceHandlers:静态资源
//    configureDefaultServletHandling:默认静态资源处理器
//    configureViewResolvers:视图解析器
//    configureContentNegotiation:配置内容裁决的一些参数
//    addCorsMappings:跨域
//    configureMessageConverters:信息转换器
}

webflux实现WebFluxConfigurer 接口

import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.config.WebFluxConfigurer;
 
 
@Configuration
@EnableWebFlux        //使用注解@EnableWebFlux
public class MyWebConnfig implements WebFluxConfigurer {
//    addResourceHandlers:静态资源
//    addCorsMappings:跨域
}

3.认证配置

​ Spring MVC的Security是通过Servlet的Filter实现的,而WebFlux的响应式Security是基于WebFilter实现的,由一些列的WebFilter形成的过滤器链。

3.1 Spring MVC的Security

webmvc-认证依赖于用户数据服务,需要实现UserDetailsService接口

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
 
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter implements
        AuthenticationEntryPoint,        //未验证回调
        AuthenticationSuccessHandler,        //验证成功回调
        AuthenticationFailureHandler,        //验证失败回调
        LogoutSuccessHandler {
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
 
    }
 
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
 
    }
 
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
 
    }
 
    @Override
    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
 
    }
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable().authorizeRequests().antMatchers("/swagger*/**", "/webjars/**", "/v2/api-docs").permitAll();
  
    }
 
    /**
     * 认证的服务
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
                return null;
            }
        });
    }
}

3.2 Spring Webflux的Security

webflux-认证依赖于用户数据服务,需实现ReactiveUserDetailsService

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.ReactiveUserDetailsPasswordService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
 
@Configuration
@EnableWebFluxSecurity
public class MyWebFluxSecurityConfig implements WebFilter,        //拦截器
        ServerLogoutSuccessHandler,        //登出成功回调
        ServerAuthenticationEntryPoint,        //验证入口
        ServerAuthenticationFailureHandler,        //验证成功回调
        ServerAuthenticationSuccessHandler {
 
    @Override
    public Mono<Void> commence(ServerWebExchange serverWebExchange, AuthenticationException e) {
        return null;
    }
 
    @Override
    public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException e) {
        return null;
    }
 
    @Override
    public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
        return null;
    }
 
    @Override
    public Mono<Void> onLogoutSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
        return null;
    }
 
    @Override
    public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
        return null;
    }
 
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
                .authorizeExchange()
                .anyExchange().authenticated()
                .and()
                .httpBasic().and()
                .formLogin();
        return http.build();
    }
 
    @Bean
    public ReactiveUserDetailsPasswordService cuseactiveUserDetailsPasswordService() {
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("user")
                .password("user")
                .roles("USER")
                .build();
        return new MapReactiveUserDetailsService(user);
    }
}

UserDetailsPasswordService 运行在 Servlet也就是webmvc上,ReactiveUserDetailsPasswordService 运行在WebFlux

4.Session配置

webmvc使用@EnableRedisHttpSession

webflux使用@EnableRedisWebSession、

5.swagger配置

webmvc使用@EnableSwagger2

webflux使用@EnableSwagger2WebFlux

参考:

https://www.jianshu.com/p/95eebeea9c14

webmvc和webflux的配置详解_ssehs的博客-CSDN博客_webflux和webmvc共存

Spring Boot 2.x实战91 - 响应式编程6 - 响应式安全控制(Reactive Spring Security)_汪云飞记录本的博客-CSDN博客

posted @ 2023-02-27 10:17  Little_Monster-lhq  阅读(327)  评论(0编辑  收藏  举报