• synchronizeOnSession


    boolean synchronizeOnSession = false表示该控制器是否在执行时同步session,从而保证该会话的用户串行访问该控制器。一个正在执行,另一个则等待。参考最下方实例:

    关于 synchronizeOnSession

    weyunx
    2019.01.30 14:52:23字数 363阅读 556

    本文为[原创]文章,转载请标明出处。
    原文链接:https://weyunx.com/2019/01/22/gitlab-install/
    原文出自微云的技术博客

    最近在维护一个老项目,发现了一个问题。我们新增了一个耗时较久的复杂查询的功能,页面采用了ajax异步请求数据,但是请求未返回之前,点击页面其他功能都只能打开空白页,必须等待之前的数据返回后才能开始加载,整个过程是串行等待,调试过程中发现服务器仅分配了一个线程给该用户。故查看了一下原始代码,发现web.xml中配置了如下参数:

    <init-param>
        <param-name>synchronizeOnSession</param-name>
        <param-value>true</param-value>
    </init-param>
    

    看了一下spring mvc 的说明文档,仅找到一处说明:

    Enforces the presence of a session. As a consequence, such an argument is never null. Note that session access is not thread-safe. Consider setting the RequestMappingHandlerAdapter instance’s synchronizeOnSession flag to true if multiple requests are allowed to concurrently access a session.

    因为 session 是非线程安全的,如果需要保证用户能够在多次请求中正确的访问同一个 session ,就要将 synchronizeOnSession 设置为 TRUE 。

    所以此处把synchronizeOnSession 改为 false 后,问题随之解决,调试中可以看到服务器为用户分配了多个线程。

    参考最下方实例:

    ==========================

    https://qiita.com/siumennel/items/f7d0973a0b6acbfd94b4

    spring synchronizeOnSession example

    More than 1 year has passed since last update.

    to run this synchronizeOnSession example:

    or test the synchronizeOnSession = false

    DemoApplication.java
    package com.example.demo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.ImportResource;
    
    @SpringBootApplication
    @Configuration
    @ImportResource("servlet-context.xml")
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
    
    
    HelloWorldController.java
    package com.example.demo;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    
    import org.apache.tomcat.util.http.parser.Cookie;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     *  * Spring Boot HelloWorld.  synchronizeOnSession example
     */
    @RestController
    public class HelloWorldController {
        @RequestMapping(value = "/{param}")
        public String sayHello(@PathVariable String param, HttpServletRequest request, HttpSession session) {
            System.out.println("param=" + param);
    
            Object id = session.getId();
            if (id == null) {
                System.out.println("session not exist " + id);
                //session.setAttribute("p", p);
            } else {
                System.out.println("session existed ,id=" + id);
                if (param.equals("sleep")) {
                    try {
                        Thread.sleep(15000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("wake up!");
                }
            }
            return "Hello,World! " + param;
        }
    }
    
    
    MyPostProcessor.java
    package com.example.demo;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
    
    @Component
    public class MyPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
            if (bean instanceof RequestMappingHandlerAdapter) {
                RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean;
                adapter.setSynchronizeOnSession(true);
            }
    
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }
    
    
    servlet-context.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        <context:property-placeholder
            location="classpath:*.properties" />
        <context:component-scan
            base-package="com.example.demo.MyPostProcessor" />
    
    </beans>
    

    details ref: https://github.com/siumennel/demo
    https://dzone.com/articles/creating-a-spring-boot-project-with-eclipse-and-ma

  • 相关阅读:
    listView控件演示程序
    猪悟能淘宝商品下载专家v3版开发手记
    c# WebClient类
    分隔控件splitter演示程序
    C#中SESSIONID的获取
    工具栏toolBar演示程序
    Cookie总结
    C#获取网页源码并且自动判断网页字符集编码
    如何在Google Code上建立私有代码版本库
    iOS应用程序生命周期(前后台切换,应用的各种状态)详解
  • 原文地址:https://www.cnblogs.com/hfultrastrong/p/12160558.html
Copyright © 2020-2023  润新知