我正在对Spring应用程序进行一些负载测试,现在我对它的配置有点困惑ThreadPoolTaskExecutor.
内部使用的文档ThreadPoolExecutor描述corePoolSize为"要保留在池中的线程数,即使它们是空闲的,[...]"和maximumPoolSize"池中允许的最大线程数".
这显然意味着maximumPoolSize限制池中线程的数量.但相反,限制似乎是由corePoolSize.实际上我配置只是corePoolSize与100一个让maximumPoolSize未配置(这意味着使用默认值:Integer.MAX_VALUE= 2147483647).
当我运行负载测试,我可以看到(通过查看日志),为所进行的工作线程从编号worker-1来worker-100.所以在这种情况下,线程池大小受限于corePoolSize.即使我设置maximumPoolSize为200或300,结果也完全一样.
为什么价值对maximumPoolSize我的情况没有影响?
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(100);
taskExecutor.setThreadNamePrefix("worker-");
return taskExecutor;
}
Run Code Online (Sandbox Code Playgroud)
解
我在文档中找到了解决方案:" 如果运行的corePoolSize不止于maxPoolSize,但只有队列已满,才会创建新线程 ".默认队列大小是Integer.MAX_VALUE.如果我限制队列,一切正常.
实际上我对弹簧代理的行为感到困惑.我想我知道j2ee,cglib和aspectj的代理机制之间的主要区别.我在配置类中启用了aspectj自动代理,并且aspectj包含在类路径中.
我的配置
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ApplicationConfiguration {
...
}
Run Code Online (Sandbox Code Playgroud)
AspectJ依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.5</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
通过使用这个简单的设置,我假设bean注入按预期工作.但相反,我的应用程序会生成IllegalArgumentException带有"无法将[...]字段[...]设置为com.sun.proxy.$ Proxy30"的消息.这意味着Spring使用j2ee代理服务,即使启用了aspectj代理也是如此.
最后我发现我的服务上的接口导致了这种行为.当我的服务实现任何接口时,似乎spring决定使用j2ee代理.如果我删除它们,它的工作原理.
失败:
@Service
@Validated
public class MyService implements Interface1, Interface2 {
@override
public void methodFromInterface1() {
}
@override
public void methodFromInterface2() {
}
public void serviceMethod() {
}
}
Run Code Online (Sandbox Code Playgroud)
好:
@Service
@Validated
public class MyService {
public void methodFromInterface1() {
}
public void methodFromInterface2() {
}
public void serviceMethod() {
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经明白j2ee代理需要接口.但对我来说这是新的,cglib/aspectj代理不适用于实现接口的bean.
有没有办法......
...强制春天不使用j2ee代理?
...强制spring使用cglib/aspectj代理(即使对于有接口的类)?
这是春天的错误或期望的行为吗?
编辑 …
这篇博客描述了 Spring Boot 1.4 中的一些测试改进。不幸的是,似乎缺少一些重要信息。什么静态导入需要使用的方法get(),status()并content()从下面的例子吗?
@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class UserVehicleControllerTests {
@Autowired
private MockMvc mvc;
@MockBean
private UserVehicleService userVehicleService;
@Test
public void getVehicleShouldReturnMakeAndModel() {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle")
.accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(content().string("Honda Civic"));
}
}
Run Code Online (Sandbox Code Playgroud) spring ×3
java ×2
aspectj ×1
proxy ×1
spring-boot ×1
spring-mvc ×1
testing ×1
threadpool ×1
unit-testing ×1