Java 函数内部。映射执行两次

Java 函数内部。映射执行两次,java,spring-boot,spring-security,spring-webflux,project-reactor,Java,Spring Boot,Spring Security,Spring Webflux,Project Reactor,我正在尝试在SpringBoot2.2.5.RELEASE上构建一个身份验证服务,使用反应堆栈。 几个小时以来我一直在挠头 执行.map中的函数两次。 @覆盖 公共Mono findByUsername(最终字符串用户名){ System.out.println(“findByUsername被调用”); 返回Mono.fromSupplier(()->userRepository.findByUsername(userName)).subscribeOn(调度器) .switchIfEmpty

我正在尝试在SpringBoot2.2.5.RELEASE上构建一个身份验证服务,使用反应堆栈。 几个小时以来我一直在挠头

执行
.map
中的函数两次。

@覆盖
公共Mono findByUsername(最终字符串用户名){
System.out.println(“findByUsername被调用”);
返回Mono.fromSupplier(()->userRepository.findByUsername(userName)).subscribeOn(调度器)
.switchIfEmpty(Mono.error(新用户名NotFoundException(“错误凭据”))
.map(用户->{
System.out.println(“内部findByUsername”);
新建AccountStatusUserDetailsChecker()。检查(用户);
返回(UserDetails)用户;
}).log();
}
以下是非反应性postgres回购协议(因此是上述代码中的供应商)

@存储库
@交易的
公共接口用户存储库扩展了JpaRepository{
/**
*按用户名查找用户
*
*@param username用户名
*@return用户对象
*/
用户findByUsername(字符串用户名);
}
下面是
findByUsername
函数的调用方:

@覆盖
公共Mono加载(ServerWebExchange swe){
System.out.println(“调用加载”);
final ServerHttpRequest request=swe.getRequest();
最终字符串username=request.getHeaders().getFirst(CustomHTTPHeaders.Keys.username);
最终字符串密码=request.getHeaders().getFirst(CustomHTTPHeaders.Keys.password);
final AbstractAuthenticationToken auth=新用户名PasswordAuthenticationToken(用户名、密码);
返回userDetailService.findByUsername(用户名).map(详细信息->{
System.out.println(“isnide flatmap”+Thread.currentThread().getName());
授权设置详细信息(详细信息);
SecurityContext SecurityContext=SecurityContextHolder.getContext();
if(passwordEncoder.matches(auth.getCredentials().toString(),details.getPassword())){
securityContext.setAuthentication(新用户名密码AuthenticationToken(details.getUsername()、details.getPassword()、details.getAuthories());
返回securityContext;
}
setAuthentication(新用户名PasswordAuthenticationToken(details.getUsername(),null));
返回securityContext;
});
输出:

load called
findByUsername called
2020-03-17 20:04:58.281  INFO 44648 --- [oundedElastic-3] reactor.Mono.Map.1     : onSubscribe(FluxMap.MapSubscriber)
2020-03-17 20:04:58.283  INFO 44648 --- [oundedElastic-3] reactor.Mono.Map.1     : request(unbounded)
inside findByUsername
2020-03-17 20:04:58.466  INFO 44648 --- [oundedElastic-4] reactor.Mono.Map.1     : onNext(User(email=william@gmail.com, username=admin, password={bcrypt}$2a$10$EOs8VROb14e7ZnydvXECA.4LoIhPOoFHKvVF/iBZ/ker17Eocz4Vi, enabled=true, accountLocked=false, accountExpired=false, credentialsExpired=false, roles=[Role(name=role_admin, permissions=[Permission(name=CREATE_USER), Permission(name=UPDATE_USER), Permission(name=READ_USER), Permission(name=DELETE_USER), Permission(name=VERIFY_TOKEN)])]))
isnide flatmap boundedElastic-4
2020-03-17 20:04:58.598  INFO 44648 --- [oundedElastic-4] reactor.Mono.Map.1     : cancel()
2020-03-17 20:04:58.604  INFO 44648 --- [oundedElastic-4] reactor.Mono.Map.1     : onSubscribe(FluxMap.MapSubscriber)
2020-03-17 20:04:58.604  INFO 44648 --- [oundedElastic-4] reactor.Mono.Map.1     : request(unbounded)
inside findByUsername
2020-03-17 20:04:58.608  INFO 44648 --- [oundedElastic-3] reactor.Mono.Map.1     : onNext(User(email=william@gmail.com, username=admin, password={bcrypt}$2a$10$EOs8VROb14e7ZnydvXECA.4LoIhPOoFHKvVF/iBZ/ker17Eocz4Vi, enabled=true, accountLocked=false, accountExpired=false, credentialsExpired=false, roles=[Role(name=role_admin, permissions=[Permission(name=CREATE_USER), Permission(name=UPDATE_USER), Permission(name=READ_USER), Permission(name=DELETE_USER), Permission(name=VERIFY_TOKEN)])]))
isnide flatmap boundedElastic-3
2020-03-17 20:04:58.716  INFO 44648 --- [oundedElastic-3] reactor.Mono.Map.1     : onComplete()
Web安全配置:

package com.turtlemint.authservice.config;
导入com.turtlemint.authservice.controller.SecurityContextRepository;
导入com.turtlemint.authservice.service.impl.AuthenticationManager;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.context.annotation.Bean;
导入org.springframework.http.HttpMethod;
导入org.springframework.http.HttpStatus;
导入org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
导入org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
导入org.springframework.security.config.web.server.ServerHttpSecurity;
导入org.springframework.security.crypto.factory.PasswordEncoderFactorys;
导入org.springframework.security.crypto.password.PasswordEncoder;
导入org.springframework.security.web.server.SecurityWebFilterChain;
导入reactor.core.publisher.Mono;
/**
*
*此类持有spring安全配置
*

* *@作者praveenkamath *创建于20年3月9日 *@自1.0.0以来 */ @启用WebFluxSecurity @EnableReactiveMethodSecurity 公共类Web安全配置{ @自动连线 AuthenticationManager AuthenticationManager; @自动连线 私人证券内容临时存储证券内容临时存储; /** *提供密码编码器 * *@返回密码编码器实例 */ @豆子 公共密码编码器PasswordEncoder(){ 返回PasswordEncoderFactorys.createDelegatingPasswordEncoder(); } /** *为安全性配置端点 * *@param http安全性 */ @豆子 公共安全WebFilterChain安全WebFilterChain(最终服务器HttpSecurity http){ 返回http.cors().disable() .例外处理() .authenticationEntryPoint((swe,e)->Mono.fromRunnable(()->{ swe.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); })).accessDeniedHandler((swe,e)->Mono.fromRunnable(()->{ swe.getResponse().setStatusCode(HttpStatus.FORBIDDEN); })).及() .csrf().disable() .authenticationManager(authenticationManager) .securityContextRepository(securityContextRepository) .授权交易所() //.pathMatchers(“/api/**”).permitAll() .pathMatchers(HttpMethod.OPTIONS).permitAll() .anyExchange().authenticated() .及() .build(); } }
不知道这是ProjectReactor中的bug还是我的代码中的bug。
请帮助。

尝试将
从供应商
切换到
从可调用
尝试在
映射
之前添加
publishOn(Schedulers.newParallel(“any”)
。我假设
userRepository.findByUsername(userName)
与jdbc池相关,在db查询之后,它会使您的
boundedElastic-4
被取消。