java - 如何通过 Spring 中的并发调用来限制方法?

标签 java spring spring-mvc

是否可以使用任何 Spring 库来“限制”方法的并发调用数?喜欢:

@RestController
public class MyRest {
   @RequestMethod
   public void call() {
         someLongRunningSyncTask();
         return "finished"; 
   } 

    public void someLongRunningSyncTask() {

    }
}

假设我希望此方法在已经有 5 个其他线程正在运行此方法的情况下延迟任何执行(以及其余 web 服务响应)。

是否有任何注释或其他抽象层已经为我提供了该行为?

最佳答案

有一个接口(interface) HandlerInterceptorAdapter 可以被实现来拦截 spring mvc 请求。 Spring 还在 HandlerInterceptorAdapter 中提供了它的抽象实现,因此您可以扩展它并覆盖您需要的任何方法。从您的描述看来,您只需要覆盖 preHandlepostHandle 方法。你可以看看this发布进一步的例子。以下是您如何使用您认为方便的任何锁定策略来实现您所需要的;

public class CustomInterceptor extends HandlerInterceptorAdapter {

    private final Semaphore semaphore;
    private final long waitTime;

    public CustomInterceptor() {
        // Hardcode this values or inject through spring as preferred.
        semaphore = new Semaphore(5);
        waitTime = 10;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            boolean acquired = semaphore.tryAcquire(1, waitTime, TimeUnit.SECONDS);
            if (!acquired) {
                //TODO Do something with the response or keep waiting or whatever 
            }
        } catch (InterruptedException e) {
            // Do something with this exception. Write custom message to response and then return false.
            // TODO write custom message to response i.e interrupted or something
            return false;
        }
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        semaphore.release();
        super.postHandle(request, response, handler, modelAndView);
    }

}

然后在spring xml或java config中实例化并注入(inject)SimpleUrlHandlerMapping的interceptors属性如下;

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/welcome">welcomeController</prop>
        </props>
    </property>
    <property name="interceptors">
        <list>
            <ref bean="customInterceptor" />
        </list>
    </property>
</bean>

<bean id="customInterceptor" class="com.common.mvc.interceptors.CustomInterceptor" />

PS: 尚未测试编码,但您应该了解基本概念。

关于java - 如何通过 Spring 中的并发调用来限制方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40378305/

相关文章:

java - Integer.decode() Java/C#

Spring Security 自定义 PermissionEvaluator 配置无法正常工作

java - 在 MVC WAR 和 Batch Jar 之间共享 Spring 应用程序上下文

spring - 使用自定义 UserDetails 实现测试 Spring Security 和 MvcMock

java - 在测试中使用@MockBean 会强制重新加载应用程序上下文

spring-mvc - Web 应用程序上下文/根应用程序上下文和事务管理器设置

spring - 我将如何为每个请求提供数千个文件

java - Spring Boot Apache Camel Quartz JDBC 调度器

java - 在请求中提供 pdf 会导致空响应

Java - 生成一组不重复的随机数