This commit is contained in:
dzc committed 2026-10-22 14:16:46 +08:00
1 parent f4c4390352
commit 4a3c8c1938
2 files changed
+93

No files matched your search

@@ -2,6 +2,7 @@ package com.bsd.pjcloud.hard.task;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.concurrent.DelegatingSecurityContextExecutor;
@@ -12,6 +13,7 @@ import java.util.concurrent.Executors;
public class ExecutorConfig {
@Bean
@Primary
public ThreadPoolTaskExecutor hardTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
@@ -0,0 +1,91 @@
package com.bsd.pjcloud.hard.task;
import com.bsd.pjcloud.common.asynctask.config.AsyncTaskAutoConfiguration;
import com.bsd.pjcloud.common.asynctask.service.AsyncTaskExecutorService;
import com.bsd.pjcloud.common.core.config.AsyncConfiguration;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.transaction.support.TransactionTemplate;
import static com.bsd.pjcloud.common.asynctask.config.AsyncTaskAutoConfiguration.ASYNC_TASK_WORKER_EXECUTOR_BEAN_NAME;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/** 验证新增公共任务线程池后,实际 Spring 容器仍能确定默认异步执行器。 */
class ExecutorConfigContextTest {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withUserConfiguration(ExecutorConfig.class)
.withConfiguration(AutoConfigurations.of(AsyncConfiguration.class));
@Test
void originalSingleExecutorStartsWithoutPrimary() {
withoutPrimary(contextRunner).run(context -> {
assertThat(context).hasNotFailed();
assertThat(context.getBean(AsyncConfiguration.class).getAsyncExecutor())
.isSameAs(context.getBean("hardTaskExecutor"));
});
}
@Test
void addingCommonExecutorWithoutPrimaryReproducesStartupFailure() {
withoutPrimary(withCommonExecutor()).run(context -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class)
.hasStackTraceContaining("hardTaskExecutor,commonAsyncTaskWorkerExecutor");
});
}
@Test
void primaryKeepsDefaultAsyncAndCommonTaskExecutorsSeparate() {
withCommonExecutor().run(context -> {
assertThat(context).hasNotFailed();
assertThat(context.getBeansOfType(ThreadPoolTaskExecutor.class))
.containsOnlyKeys("hardTaskExecutor", ASYNC_TASK_WORKER_EXECUTOR_BEAN_NAME);
assertThat(context.getBean(AsyncConfiguration.class).getAsyncExecutor())
.isSameAs(context.getBean("hardTaskExecutor"));
assertThat(ReflectionTestUtils.getField(context.getBean(AsyncTaskExecutorService.class),
"asyncTaskWorkerExecutor"))
.isSameAs(context.getBean(ASYNC_TASK_WORKER_EXECUTOR_BEAN_NAME));
});
}
private ApplicationContextRunner withCommonExecutor() {
return contextRunner.withUserConfiguration(TestInfrastructure.class)
.withConfiguration(AutoConfigurations.of(AsyncTaskAutoConfiguration.class))
.withInitializer(context -> context.addBeanFactoryPostProcessor(beanFactory -> {
// 公共工厂方法返回接口类型,先实例化才能暴露真实线程池类型;覆盖线上触发冲突的顺序。
for (String name : beanFactory.getBeanNamesForType(AsyncConfiguration.class, false, false)) {
beanFactory.getBeanDefinition(name).setDependsOn(ASYNC_TASK_WORKER_EXECUTOR_BEAN_NAME);
}
}));
}
private ApplicationContextRunner withoutPrimary(ApplicationContextRunner runner) {
return runner.withInitializer(context -> context.addBeanFactoryPostProcessor(beanFactory ->
beanFactory.getBeanDefinition("hardTaskExecutor").setPrimary(false)));
}
@Configuration(proxyBeanMethods = false)
static class TestInfrastructure {
@Bean
@SuppressWarnings("unchecked")
RedisTemplate<String, Object> redisTemplate() {
return mock(RedisTemplate.class);
}
@Bean
TransactionTemplate transactionTemplate() {
return mock(TransactionTemplate.class);
}
}
}