2012-05-01 10 views
10

Quiero iniciar un hilo de servicio de correo daemon en el arranque del servidor tomcat. Entonces, he anotado un método con la anotación @Async.Cómo iniciar un daemon en el inicio del servidor en la primavera

Tengo una clase que implementa una interfaz ApplicationListener. Cuando llamo a mi método asíncrono de esta clase, nunca comienza de forma asíncrona y bloquea el hilo actual. Y cuando llamo a mi método asíncrono desde una clase de controlador de primavera, nunca se bloquea y comienza de forma asíncrona.

¿Por qué el método asíncrono se ejecutó correctamente desde una clase y no desde la otra clase?

¿Qué estoy haciendo mal y cómo puedo ejecutar mi método async en el inicio del servidor?

Gracias de antemano.

Editar: Hola chicos, He intentado utilizar la interfaz InitializingBean, @PostConstruct, init-método de aproximación a llamar a mi método asíncrono, pero nunca ejecutado. Entonces me di cuenta de que mi valor predeterminado lazy-init es verdadero, así que hago que lazy-init sea falsa para InitializingBean. Ahora ejecuta mi método asnyc, pero bloquea el hilo actual y ahora un problema más, me estoy enfrentando es que Mi servidor no se detuvo con gracia, pero tengo que detener mi servidor con fuerza.

+2

Muéstranos tu código. –

Respuesta

12

Antes que nada No necesita implementar la interfaz ApplicationListener. Estás trabajando con Spring - El contexto de la aplicación es suficiente.

En segundo lugar, está hablando de Spring @Async, significa que su tarea debe iniciarse desde Application Context y Controller bean es parte de ella.

Debe asegurarse de tener <annotation-driven> en su archivo xml de primavera.

Usted puede comenzar su tarea en la función @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(); 
    } 
} 
+0

Hola Danny, gracias, una pregunta más, ¿cómo puedo ejecutar algún método en el inicio del servidor, si no implementaré la interfaz ApplicationListener? –

+0

ver mi respuesta actualizada. –

+1

La solución aceptada no funcionará como se indica en el siguiente error: https://jira.spring.io/browse/SPR-7560 –

0

@asyn es algo que forma parte de spring framework, ¿Su contexto de uso del oyente es el contexto? Si no, sugeriré que comience un nuevo hilo en su método asíncrono.

4

Sobre la base de, uso de @Async tiene limitaciones durante la puesta en marcha de la aplicación de reference primavera:

@Async no se puede utilizar junto con devoluciones de llamadas del ciclo de vida como @PostConstruct. Para inicializar asincrónicamente los beans de primavera, actualmente tiene que usar un bean de inicialización separado que invoque el método anotado @Async en el destino.

Entonces, en su caso, tal vez sería bueno tener una implementación InitializingBean con su bean objetivo y luego iniciar el daemon a través de eso.

2

¿Ha agregado la etiqueta <annotation-driven> al contexto de su aplicación? Desde el Spring reference doc:

para permitir @Scheduled y @Async anotaciones, sólo tiene que incluir el elemento 'anotación impulsada' del espacio de nombres de tareas de su configuración.

Nota, también se debe considerar para configurar un ejecutor ejemplo. Desde el task schema definition:

define una instancia ThreadPoolTaskExecutor con el tamaño de la piscina configurable, cola de capacidad, keep-alive, y los valores de rechazo a las políticas. Consulte Javadoc para la anotación org.springframework.scheduling.annotation.EnableAsync para obtener información sobre las alternativas basadas en código para este elemento XML.

Así que para crear un ejecutor que está respaldado por un grupo de subprocesos con 5 hilos que tiene que hacer lo siguiente:

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

Para más opciones de configuración, ver la @EnableAsync javadoc como se indicó anteriormente.

1

my english is pool. debe establecer la clase de servicio @Lazy (falso).

Cuestiones relacionadas