当前位置:首页 » 《随便一记》 » 正文

SpringWebmvc和SpringWebflux

8 人参与  2024年11月18日 12:01  分类 : 《随便一记》  评论

点击全文阅读


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


点击全文阅读


本文链接:http://zhangshiyu.com/post/188105.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1