java 如何在春季服务器启动时启动守护进程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10395204/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 00:52:48  来源:igfitidea点击:

How to start a daemon on server startup in spring

javaspring

提问by Dheeraj Kumar Aggarwal

I want to start a daemon mail service thread on tomcat server startup. So, I have annotated a method with @Async annotation.

我想在 tomcat 服务器启动时启动一个守护进程邮件服务线程。所以,我用@Async 注释注释了一个方法。

I have a class which implements a ApplicationListener interface. When I call my async method from this class, it never starts asynchronously and blocks the current thread. And When I call my async method from a spring controller class, It never blocks and starts asynchronously.

我有一个实现 ApplicationListener 接口的类。当我从这个类调用我的异步方法时,它永远不会异步启动并阻塞当前线程。当我从 spring 控制器类调用我的异步方法时,它永远不会阻塞并异步启动。

Why async method executed successfully from one class and not from the other class?

为什么异步方法从一个类而不是从另一个类成功执行?

What am I doing wrong and How can I execute my async method on server startup??

我做错了什么,如何在服务器启动时执行我的异步方法?

Thanks in advance.

提前致谢。

Edit:Hi Guys, I tried using the InitializingBean interface, @PostConstruct, init-method approach to call my async method, but it never executed. Then I realized, my default lazy-init is true, So I make the lazy-init to false for my InitializingBean. Now it execute my asnyc method, but it blocks the current thread and now one more issue, I am facing is that My server didn't stop gracefully, but I have to stop my server forcefully.

编辑:大家好,我尝试使用 InitializingBean 接口、@PostConstruct、init-method 方法来调用我的异步方法,但它从未执行过。然后我意识到,我默认的lazy-init 是true,所以我将我的InitializingBean 的lazy-init 设置为false。现在它执行我的 asnyc 方法,但它阻塞了当前线程,现在我面临的另一个问题是我的服务器没有正常停止,但我必须强行停止我的服务器。

回答by danny.lesnik

First of all You don't need to implement ApplicationListenerinterface. You are working with Spring - Application context is enough.

首先你不需要实现ApplicationListener接口。您正在使用 Spring - 应用程序上下文就足够了。

Second you are talking about Spring @Async, it means that your task should be started from Application Context and Controller bean is a part of it.

其次,您在谈论 Spring @Async,这意味着您的任务应该从 Application Context 开始,Controller bean 是其中的一部分。

You need to make sure that you have <annotation-driven>in your spring xml file.

您需要确保<annotation-driven>您的 spring xml 文件中有。

You can start your task on @PostConstruct function:

您可以在@PostConstruct 函数上开始您的任务:

@Component
public class SampleBeanImpl implements SampleBean {

  @Async
  void doSomething() { … }
}


@Component
public class SampleBeanInititalizer {

  @Autowired
  private final SampleBean bean;

  @PostConstruct
  public void initialize() {
    bean.doSomething();
  }
}

回答by nobeh

Based on Spring's reference, use of @Asynchas limitations during start-up of the application:

根据 Spring 的参考@Async在应用程序启动期间使用有限制:

@Asynccan not be used in conjunction with lifecycle callbacks such as @PostConstruct. To asynchronously initialize Spring beans you currently have to use a separate initializing Spring bean that invokes the @Asyncannotated method on the target then.

@Async不能与生命周期回调(例如 @PostConstruct. 要异步初始化 Spring bean,您目前必须使用一个单独的初始化 Spring bean,然后调用@Async目标上的带 注释的方法。

So, in your case, maybe it'd be good to have an InitializingBeanimplementation with your target bean and then start the daemon through that.

所以,在你的情况下,也许最好InitializingBean用你的目标 bean 实现,然后通过它启动守护进程。

回答by matsev

Have you added the <annotation-driven>tag to your application context? From the Spring reference doc:

您是否已将<annotation-driven>标签添加到您的应用程序上下文中?从Spring 参考文档

To enable both @Scheduled and @Async annotations, simply include the 'annotation-driven' element from the task namespace in your configuration.

要同时启用 @Scheduled 和 @Async 注释,只需在配置中包含任务命名空间中的“注释驱动”元素。

Note, you should also consider to configure an executorinstance. From the task schema definition:

请注意,您还应该考虑配置一个执行程序实例。从任务架构定义

Defines a ThreadPoolTaskExecutor instance with configurable pool size, queue-capacity, keep-alive, and rejection-policy values. See Javadoc for the org.springframework.scheduling.annotation.EnableAsync annotation for information on code-based alternatives to this XML element.

使用可配置的池大小、队列容量、保持活动和拒绝策略值定义一个 ThreadPoolTask​​Executor 实例。有关此 XML 元素的基于代码的替代方案的信息,请参阅 org.springframework.scheduling.annotation.EnableAsync 注释的 Javadoc。

So to create an executor that is backed up by a thread pool with 5 threads you have to do the following:

因此,要创建一个由具有 5 个线程的线程池支持的执行程序,您必须执行以下操作:

<task:annotation-driven executor="myExecutor"/>
<task:executor id="myExecutor" pool-size="5"/>

For more configuration options, see the @EnableAsync javadocas stated above.

有关更多配置选项,请参阅上述@EnableAsync javadoc

回答by yejianmail

my english is pool. you must set the Service Class @Lazy(false).

我的英语是游泳池。您必须设置服务类@Lazy(false)。

回答by Vijay Shanker Dubey

@asynis something part of spring framework, Does your listener usage spring context? If not, I will suggest to start a new thread in your async method.

@asyn是 spring 框架的一部分,您的听众是否使用 spring 上下文?如果没有,我会建议在您的异步方法中启动一个新线程。