从 CompletableFuture 线程中的主线程访问 SessionScoped bean 不起作用

问题描述

我是 Spring Boot 开发的新手。我需要使用 CompletableFuture 并行运行几个任务,还需要从 CompletableFuture 线程内的主线程访问 SessionScoped bean。根据尝试从 HelloService.CompletableFuture1() 调用 helloBean.getHelloMessage() 时的打击代码,它会停止进一步处理。任何帮助将不胜感激。

SessionScopeWithCfApplication.java

@EnableAsync
@SpringBootApplication
public class SessionScopeWithCfApplication {

    public static void main(String[] args) {
        SpringApplication.run(SessionScopeWithCfApplication.class,args);
    }

}

=====

HelloBean.java

public class HelloBean {

    private String helloMessage;

    public String getHelloMessage() {
        return helloMessage;
    }

    public void setHelloMessage(String helloMessage) {
        this.helloMessage = helloMessage;
    }


}

=====

HelloBeanScopeConfig.java

@Configuration
public class HelloBeanScopeConfig {

    @Bean
    //@SessionScope
    //@Scope(value = "session",proxyMode = ScopedProxyMode.TARGET_CLASS)
    @Scope(value = WebApplicationContext.ScopE_SESSION,proxyMode = ScopedProxyMode.TARGET_CLASS)
    public HelloBean helloBean() {
        return new HelloBean();
    }

}

=====

HelloController.java

@Controller
public class HelloController {

    @Resource(name = "helloBean")
    HelloBean helloBean;
    
    @RequestMapping(value = {"/"},method = RequestMethod.GET)
    public String home(Model model,HttpServletRequest request) {
        System.out.println("HelloController.home() - helloBean.getHelloMessage() = " + helloBean.getHelloMessage());
        helloBean.setHelloMessage("Welcome");
        System.out.println("HelloController.home() - helloBean.getHelloMessage() = " + helloBean.getHelloMessage());
    return "index";
    }
    
}

=====

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
    <Meta charset="utf-8" />
    <Meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <Meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>Login</title>
    <link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/3.3.6/css/bootstrap.min.css}" />
        <script type='text/javascript' th:src="@{/webjars/jquery/1.9.1/jquery.min.js}"></script>
    <script type="text/javascript" th:src="@{/webjars/bootstrap/3.3.6/js/bootstrap.min.js}"></script>
    <script type='text/javascript'>
        function getHelloMessage() {
            return $.ajax({
                url: '/gethellomessage',method: 'get',contentType: "application/json; charset=utf-8",});
        };
        $(document).ready(function() {
            $('#btn').on('click',function () {
                getHelloMessage();
            }); 
        });
    </script>
</head>
<body>
    <div>
        <button id="btn" type="submit" class="btn btn-primary">Click Me</button>
    </div>
</body>
</html>

=====

HelloRestController.java

@RestController
public class HelloRestController {

    @Autowired
    HelloService helloService;
    
    @Resource(name = "helloBean")
    HelloBean helloBean;
    
    @RequestMapping(value = "/gethellomessage",method = RequestMethod.GET)
    public ResponseEntity getHelloMessage() {
    try {
            System.out.println("HelloRestController.getHelloMessage() - helloBean.getHelloMessage() = " + helloBean.getHelloMessage());
            helloService.CompletableFuture1();
            //CompletableFuture.allOf(helloService.CompletableFuture1()).get();
            return new ResponseEntity(HttpStatus.OK);
    } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
    }        
    }

}

=====

HelloService.java

@Service
public class HelloService {

    @Resource(name = "helloBean")
    HelloBean helloBean;

    @Async
    @Scope(value = WebApplicationContext.ScopE_SESSION,proxyMode = ScopedProxyMode.TARGET_CLASS)
    public CompletableFuture<Void> CompletableFuture1() {
        System.out.println("executing CompletableFuture1 by - "+Thread.currentThread().getName());
    try {
            System.out.println("CompletableFuture1 - helloBean.getHelloMessage() = " + helloBean.getHelloMessage());
        Thread.sleep(5000);
            System.out.println("Done CompletableFuture1");
    } catch (Exception e) {
            throw new RuntimeException((new Exception().getStackTrace()[0].getmethodName()) + ": " + e.getClass().getSimpleName() + ": " + e.getMessage());
    }
        return CompletableFuture.completedFuture(null);
    }
    
}


Output:

HelloController.home() - helloBean.getHelloMessage() = null
HelloController.home() - helloBean.getHelloMessage() = Welcome
HelloRestController.getHelloMessage() - helloBean.getHelloMessage() = Welcome
executing CompletableFuture1 by - task-1

It is not printing value from HelloService.CompletableFuture1() for the below command and stops processing at this stage:
    
System.out.println("CompletableFuture1 - helloBean.getHelloMessage() = " + helloBean.getHelloMessage());

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)