如何在Spring中限制方法的并发调用?

3

是否有可能使用任何Spring库来“节流”方法的并发调用数量?类似于:

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

    public void someLongRunningSyncTask() {

    }
}

假设我想要这个方法延迟任何执行(以及其它Web服务响应),如果已经有5个线程正在运行此方法。

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

1个回答

1

有一个接口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配置中实例化,并将其注入到SimpleUrlHandlerMapping的拦截器属性中,如下所示;

<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" />

提示:尚未测试代码,但您应该能够了解基本思路。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接