我在 Scala 中有一个带有多个端点的 Spring Boot API。所有端点都是async并 return DeferredResult。在某些情况下,我想使用过滤器来记录响应正文。我创建了一个顺序为 1 的过滤器来缓存请求和响应,如下所示:
@Component
@Order(1)
class ContentCachingFilter extends OncePerRequestFilter {
override def doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain): Unit = {
val requestToCache = new ContentCachingRequestWrapper(request)
val responseToCache = new ContentCachingResponseWrapper(response)
filterChain.doFilter(requestToCache, responseToCache)
responseToCache.copyBodyToResponse()
}
}
Run Code Online (Sandbox Code Playgroud)
我的日志过滤器类似于下面(删除了域特定逻辑):
@Component
@Order(2)
class RequestResponseLoggingFilter extends OncePerRequestFilter {
override def doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain): Unit = {
logger.info(
s"Request -> URL : ${request.getMethod} ${request.getRequestURI} ${request.getParameterMap.asScala.stringRepresentation()}")
logger.debug(
s"Request Headers -> Content-type : ${request.getContentType} …Run Code Online (Sandbox Code Playgroud) 如何Spring Retry与外部调用集成AsyncRestTemplate?如果不可能,是否有其他框架支持它?
我的用例:
public void doSomething() throws ExecutionException, InterruptedException {
ListenableFuture<ResponseEntity<String>> future = asyncRestTemplate.getForEntity("http://localhost/foo", String.class);
// do some tasks here
ResponseEntity<String> stringResponseEntity = future.get(); // <-- How do you retry just this call?
}
Run Code Online (Sandbox Code Playgroud)
您如何重试此future.get()呼叫?如果外部服务返回 404,我想避免再次调用这些任务,而只是重试外部调用?我不能只future.get()用 a换行retryTemplate.execute(),因为它实际上不会再次调用外部服务。
特定 bean 的初始化需要执行网络连接。这可能需要一些时间,并且不必要地将已经很长时间的启动阻塞几秒钟。
有什么方法可以让我的 bean 发出信号,即使它退出构造函数后它仍未初始化,然后在它准备就绪后,向上下文发出信号,表明它现在已准备就绪,并且它的状态应移至“已初始化” .
你能告诉我 Spring 的默认参数是什么,@Async ThreadPoolTaskExecutor或者我怎么能找到我自己的参数?
maxPoolSize、corePoolSize 和 queueCapcity 的默认值是什么?
我应该覆盖它们以改进我的应用程序还是使用默认值就可以了?
我必须在 Spring Boot 中实现具有异步功能的方法:
我对注释异步的位置有点困惑,基本上我的休息控制器如下:
@RestController
@RequestMapping("/email")
public class EmailController {
public @ResponseBody ResponseEntity<String> sendMailCon(@RequestBody EmailRequestDto emailRequestDto) {
LOG.debug("calling method sendMail from controller ");
//do complex stuff
sendMailService.sendEmail(emailRequestDto);
return new ResponseEntity<>("Mail has been sent successfully", HttpStatus.OK);
}
Run Code Online (Sandbox Code Playgroud)
服务等级如下:
@Component
public class SendMailServiceImpl implements SendMailService {
private static final Logger LOG = LoggerFactory.getLogger(SendMailServiceImpl.class);
@Autowired
private JavaMailSender javaMailSender;
@Override
@Async("threadPoolExecutor")
public void sendEmail(EmailRequestDto emailRequestDto) {
LOG.debug("calling method sendMail do complex stuff");
...
}
Run Code Online (Sandbox Code Playgroud)
我的异步 bean 配置如下:
@EnableAsync
@Configuration
public class AsyncConfig { …Run Code Online (Sandbox Code Playgroud) 如果你有一个 @Async 方法,它返回一个CompletableFuture.... 并且 future永远不会完成,spring 是否会泄漏线程?是的,我知道任何等待结果的人都可能超时并假设后期阶段异常完成......但这不会停止线程。即使你调用cancel,它也不会影响正在运行的线程:
来自文档:
@param mayInterruptIfRunning 该值在此实现中无效,因为中断不用于控制处理。
如果我使用 Future 而不是 CompletableFuture,cancel将会中断线程。不幸的是,Future 上没有相当于 CompletableFuture 上的“allOf”来等待所有任务,如下所示:
// wait for all the futures to finish, regardless of results
CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new))
// if exceptions happened in any future, swallow them
// I don't care because I'm going to process each future in my list anyway
// we just wanted to wait for all the futures to finish
.exceptionally(ex -> null);
Run Code Online (Sandbox Code Playgroud)
multithreading java.util.concurrent spring-boot spring-async java-11
我正在使用编写集成测试SpringJUnit4ClassRunner。我有一个基类:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({ /*my XML files here*/})
@Ignore
public class BaseIntegrationWebappTestRunner {
@Autowired
protected WebApplicationContext wac;
@Autowired
protected MockServletContext servletContext;
@Autowired
protected MockHttpSession session;
@Autowired
protected MockHttpServletRequest request;
@Autowired
protected MockHttpServletResponse response;
@Autowired
protected ServletWebRequest webRequest;
@Autowired
private ResponseTypeFilter responseTypeFilter;
protected MockMvc mockMvc;
@BeforeClass
public static void setUpBeforeClass() {
}
@AfterClass
public static void tearDownAfterClass() {
}
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).addFilter(responseTypeFilter).build();
}
@After
public void tearDown() {
this.mockMvc = null;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我将其扩展并使用mockMvc创建一个测试: …
考虑以下代码:
@RestController
@RequestMapping("/timeout")
public class TestController {
@Autowired
private TestService service;
@GetMapping("/max10secs")
public String max10secs() {
//In some cases it can take more than 10 seconds
return service.call();
}
}
@Service
public class TestService {
public String call() {
//some business logic here
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
我想要完成的是,如果call来自的方法TestService需要超过 10 秒,我想取消它并使用HttpStatus.REQUEST_TIMEOUT代码生成响应。
spring request-timed-out spring-boot spring-restcontroller spring-async
我正在使用Spring Boot应用程序。我有一个返回Callable的rest控制器。
@GetMapping("/fb-roles")
@Timed
public Callable<List<FbRole>> getAllFbRoles() {
log.debug("REST request to get all FbRoles");
return (() -> { return fbRoleRepository.findAll(); });
}
Run Code Online (Sandbox Code Playgroud)
ThreadPoolTaskExecutor的配置如下:
@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfiguration implements AsyncConfigurer {
private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class);
private final JHipsterProperties jHipsterProperties;
public AsyncConfiguration(JHipsterProperties jHipsterProperties) {
this.jHipsterProperties = jHipsterProperties;
}
@Override
@Bean(name = "taskExecutor")
public Executor getAsyncExecutor() {
log.debug("Creating Async Task Executor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(jHipsterProperties.getAsync().getCorePoolSize());
executor.setMaxPoolSize(jHipsterProperties.getAsync().getMaxPoolSize());
executor.setQueueCapacity(jHipsterProperties.getAsync().getQueueCapacity());
executor.setThreadNamePrefix("fb-quiz-Executor-");
return new ExceptionHandlingAsyncTaskExecutor(executor);
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { …Run Code Online (Sandbox Code Playgroud) 我有一个调用两个单独线程的线程。CompletableFuture它向这两个子线程传递相同的内容。如果.get()同时在这两个线程中调用,我会遇到任何类型的并发问题吗?
CompletableFuture?.get()?作为一个具体的例子,在下面的代码中,假设完成cfInput.get()后返回的对象没有发生任何变化,两个线程是否有可能打印不同的值?cfInput
public void mainClass(CompletableFuture<ObjA> cfInput){\n class1.doAsync1(cfInput);\n class2.doAsync2(cfInput);\n}\n\n@Async\npublic void doAsync1(CompletableFuture<ObjA> cfInput){\n //logic\n System.out.println(cfInput.get().getObjB().getBlah());\n //logic\n}\n\n@Async\npublic void doAsync2(CompletableFuture<ObjA> cfInput){\n //logic\n System.out.println(cfInput.get().getObjB().getBlah());\n //logic\n}\n\npublic class ObjA{\n private ObjB objB;\n public ObjB getObjB();\n public void setObjB();\n}\npublic class ObjB{\n private String blah;\n public String getBlah();\n public void setBlah();\n}\nRun Code Online (Sandbox Code Playgroud)\n 我读过代码但没有找到ThreadPoolTaskExecutor的默认池类型。ThreadPoolTaskExecutor的默认线程池是什么?newFixedThreadPool 还是 newCachedThreadPool?
我有一个 Spring Boot 2.2 应用程序。我创建了一个这样的服务:
@Async
@PreAuthorize("hasAnyRole('ROLE_PBX')")
@PlanAuthorization(allowedPlans = {PlanType.BUSINESS, PlanType.ENTERPRISE})
public Future<AuditCdr> saveCDR(Cdr3CXDto cdrRecord) {
log.debug("Current tenant {}", TenantContext.getCurrentTenantId());
return new AsyncResult<AuditCdr>(auditCdrRepository.save(cdr3CXMapper.cdr3CXDtoToAuditCdr(cdrRecord)));
}
Run Code Online (Sandbox Code Playgroud)
这是我的@Async 配置:
@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("threadAsync");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}
}
Run Code Online (Sandbox Code Playgroud)
使用SecurityContextHolder.MODE_INHERITABLETHREADLOCAL我看到安全上下文被传递给@Async 方法。在我的多租户应用程序中,我使用 ThreadLocal 来设置租户的 id:
public class TenantContext {
public final static String TENANT_DEFAULT = "empty";
private static final ThreadLocal<String> code = new …Run Code Online (Sandbox Code Playgroud) @Async这是Spring Boot 中正确的使用方法吗?
@Service
class someServiceImpl {
...
public someResponseDTO getUsers(int userId) {
// Do some logic
...
// Call external API with another service method from another service impl
anotherService.emailUserInTheBackground(userId);
return someResponseDTO;
}
...
}
Run Code Online (Sandbox Code Playgroud)
@Service
public class AnotherService {
@Async
public void emailUserInTheBackground(int userId) {
// This might take a while...
...
}
}
Run Code Online (Sandbox Code Playgroud)
既然emailUserInTheBackground()有@Async注释和返回类型,它会完全void阻塞该行吗?return someResponseDTO
我想要的只是将响应返回给调用者而无需等待,因为emailUserInTheBackground()完成时间太长并且不直接绑定到响应对象。
spring-async ×13
java ×8
spring ×8
spring-boot ×7
spring-mvc ×2
asynchronous ×1
java-11 ×1
jhipster ×1
junit ×1
spring-bean ×1
spring-retry ×1
spring-test ×1