每次tomcat创建新Thread时如何运行DelegatingSecurityContextRunnable

Tit*_*ito 5 spring spring-security spring-boot

我有一个使用带有websockets的tomcat的spring应用程序.每当tomcat创建一个新线程时,我想使用DelegatingSecurityContextRunnable,即warp tomcat线程.有谁知道这是怎么做的.可以找到问题的原因.这里

也许这可以通过使用AOP和一些建议来完成?

pan*_*adb 1

在 Spring boot 中,您可以通过挂接到 Tomcat 连接器来配置 Wrapper。以此为例:

@Bean
    public EmbeddedServletContainerFactory servletContainerFactory() {
        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();

        factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {

            @Override
            public void customize(Connector connector) {
                AbstractProtocol protocolHandler = (AbstractProtocol) connector.getProtocolHandler();
                TaskQueue taskqueue = new TaskQueue() {
                    @Override
                    public boolean offer(Runnable e, long timeout, TimeUnit unit) throws InterruptedException {
                        return super.offer(new MyRunnable(e), timeout, unit);
                    }

                    @Override
                    public boolean offer(Runnable o) {
                        return super.offer(new MyRunnable(o));
                    }
                };
                TaskThreadFactory tf = new TaskThreadFactory("artur-" + "-exec-", false, 0);
                ThreadPoolExecutor e = new ThreadPoolExecutor(10, 10, 1000, TimeUnit.SECONDS, taskqueue);
                taskqueue.setParent(e);
                protocolHandler.setExecutor(e);
            }
        });
        return factory;
    }
Run Code Online (Sandbox Code Playgroud)

这是我的自定义 Runable(这可以是任何包装器,我没有费心实现您的):

static class MyRunnable implements Runnable {

        private Runnable r;

        public MyRunnable(Runnable r) {
            this.r = r;
        }

        @Override
        public void run() {
            System.out.println("Custom runable");
            runInner();
        }

        void runInner() {
            r.run();
        }

    }
Run Code Online (Sandbox Code Playgroud)

这是我的进口:

import java.util.concurrent.TimeUnit;

import org.apache.catalina.connector.Connector;
import org.apache.coyote.AbstractProtocol;
import org.apache.tomcat.util.threads.TaskQueue;
import org.apache.tomcat.util.threads.TaskThreadFactory;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.PropertySource;
Run Code Online (Sandbox Code Playgroud)

这是做什么的:

Tomcat 连接器会自行初始化。您可以设置要使用的执行器,在这种情况下,Tomcat 将停止创建自己的配置,而是使用您的配置。

通过覆盖队列中的 Offer 方法,您有机会将您的方法包装Runnable在任何自定义的Runnable. 就我而言,为了进行测试,我只是添加了一个Sysout来查看一切是否正常工作。

我使用的实现Threadpool是 tomcat 默认值的精确副本(减去属性)。这样,行为保持不变,除了 anyRunnable现在是您的委托包装器。

当我测试时,我的控制台打印:

 Custom runable
Run Code Online (Sandbox Code Playgroud)

我希望这就是您正在寻找的。

我使用 spring boot,但这本质上是 tomcat 问题而不是 spring 问题。您可以根据您的具体场景调整解决方案。

——阿图尔