如何在Spring中启动服务器启动时的守护进程

时间:2012-05-01 08:14:47

标签: java spring

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

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

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

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

提前致谢。

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

5 个答案:

答案 0 :(得分:13)

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

其次你在谈论Spring @Async,这意味着你的任务应该从Application Context启动,而Controller bean也是它的一部分。

您需要确保spring xml文件中包含<annotation-driven>

您可以在@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();
  }
}

答案 1 :(得分:4)

基于Spring的reference@Async的使用在启动应用程序时有局限性:

  

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

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

答案 2 :(得分:2)

您是否已将<annotation-driven>标记添加到应用程序上下文中?来自Spring reference doc

  

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

注意,您还应该考虑配置 executor 实例。来自task schema definition

  

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

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

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

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

@asyn是spring框架的一部分,你的监听器使用弹簧上下文吗?如果没有,我建议你在异步方法中启动一个新线程。