我正在测试一些功能,我想自定义tomcat以启用JNDI并添加一个执行程序。
然后我想配置spring的异步与从tomcat的JNDI检索的执行器。是否可以在没有“自动配置”的情况下执行此操作(或者如何在没有启动的情况下在春天执行此操作)?
当我在第一个customAsyncExecutor()
调试代码(在intellij中)时,执行tomcatFactory()
之后。我想先致电tomcatFactory()
。
这是我的代码:
package com.github.bilak.poc.async;
import java.util.concurrent.Executors;
import javax.naming.NamingException;
import org.apache.catalina.Context;
import org.apache.catalina.Executor;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.util.descriptor.web.ContextResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jndi.JndiTemplate;
import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
@SpringBootApplication
@EnableScheduling
@EnableAsync
public class TomcatAsyncConfigurationPOCApplication {
public static void main(String[] args) {
SpringApplication.run(TomcatAsyncConfigurationPOCApplication.class, args);
}
@Configuration
public static class TomcatJNDIConfiguration {
private static final Logger logger = LoggerFactory.getLogger(TomcatJNDIConfiguration.class);
private final String asyncExecutorJNDIName;
public TomcatJNDIConfiguration(@Value("${async.executor.jndi-name}") String asyncExecutorJNDIName) {
this.asyncExecutorJNDIName = asyncExecutorJNDIName;
}
@Bean
public EmbeddedServletContainerFactory tomcatFactory() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
tomcat.enableNaming();
return super.getTomcatEmbeddedServletContainer(tomcat);
}
@Override
protected void postProcessContext(Context context) {
ContextResource resource = new ContextResource();
resource.setName("asyncThreadPoolExecutor");
resource.setType(Executor.class.getName());
resource.setProperty("namePrefix", "test");
resource.setProperty("maxThreads", "2");
context.getNamingResources().addResource(resource);
}
};
return tomcat;
}
@Bean(name = "customAsyncExecutor")
java.util.concurrent.Executor customAsyncExecutor() {
JndiTemplate jndiTemplate = new JndiTemplate();
java.util.concurrent.Executor executor;
try {
executor = (java.util.concurrent.Executor) jndiTemplate.lookup(asyncExecutorJNDIName);
} catch (NamingException e) {
logger.error("Unable to find async executor {} in jndi", asyncExecutorJNDIName, e);
// TODO what will be the fallback when JNDI is not found?
executor = Executors.newSingleThreadExecutor(new CustomizableThreadFactory("ae-fallback"));
}
return executor;
}
}
@Configuration
public static class CustomAsyncConfigurerSupport extends AsyncConfigurerSupport {
private java.util.concurrent.Executor customAsyncExecutor;
public CustomAsyncConfigurerSupport(java.util.concurrent.Executor customAsyncExecutor) {
this.customAsyncExecutor = customAsyncExecutor;
}
@Override
public java.util.concurrent.Executor getAsyncExecutor() {
return customAsyncExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
}