2012-10-08 20 views
18

Me pregunto cómo pasar una variable de instancia externamente en Quartz?¿Cómo pasar variables de instancia al trabajo de Quartz?

A continuación se muestra el pseudo código que me gustaría escribir. ¿Cómo puedo pasar ExternalInstance en este trabajo?

public class SimpleJob implements Job { 
     @Override 
     public void execute(JobExecutionContext context) 
       throws JobExecutionException { 

      float avg = externalInstance.calculateAvg(); 
     } 
} 
+0

Inyectar el externalInstance en su trabajo – Anshu

Respuesta

39

puede poner su instancia en el schedulerContext.When que se va a programar el trabajo, justo antes de que usted puede hacer a continuación:

getScheduler().getContext().put("externalInstance", externalInstance); 

Su clase de trabajo sería como a continuación:

public class SimpleJob implements Job { 
    @Override 
    public void execute(JobExecutionContext context) 
      throws JobExecutionException { 
     SchedulerContext schedulerContext = null; 
     try { 
      schedulerContext = context.getScheduler().getContext(); 
     } catch (SchedulerException e1) { 
      e1.printStackTrace(); 
     } 
     ExternalInstance externalInstance = 
      (ExternalInstance) schedulerContext.get("ExternalInstance"); 

     float avg = externalInstance.calculateAvg(); 
    } 
} 

Si está utilizando Spring, puede utilizar el soporte de spring para inyectar toda la aplicaciónContext como respondió en el Link

+0

Esto funciona bien para objetos serializables, y funcionará para las clases a las que tiene acceso. ¿Qué pasa si quiero inyectar algo desde un contenedor externo? Por ejemplo, estoy tratando de escribir un StatefulJob que enumera todos los archivos en un depósito S3 desde una fecha determinada y almacena los archivos que figuran en JobDetailMap. Quiero inyectar un AmazonS3Client configurado en mi trabajo. No puedo hacer esto porque esa clase no es serializable, y entonces tengo que inyectar la clave secreta, acceder a la clave y escribir el código para administrar la creación de un cliente s3. ¿Es esa la mejor manera de hacerlo? Cualquier sugerencia sería útil. –

+0

Respondiendo a mi propia pregunta: autoajuste el trabajo, encontré esta muy buena solución en línea - http://stackoverflow.com/questions/4258313/how-to-use-autowired-in-a-quartz-job –

+1

Excelente trabajo. Me ayudó. –

5

Mientras que la programación de la tarea mediante un disparador, que habría definido JobDataMap que se añade a la JobDetail. Ese objeto JobDetail estará presente en el JobExecutionContext pasado al método execute() en su Job. Por lo tanto, debe encontrar la manera de pasar su instancia externa a través del JobDataMap. HTH.

+0

instancia externa quiero decir que podría ser cualquier tipo de datos personalizado, no se limita a tipo de datos nativo, como cuerdas, Flotador , Int, etc. Leí de la documentación, dice que la instancia necesita ser serializable. – janetsmith

+0

En nuestro caso, los objetos para trabajar son objetos DB, por lo que utilizamos almacenar los criterios para recuperarlos de DB, en JobDataMap y recuperarlos en el método de ejecución. Por lo tanto, también necesita encontrar la manera de pasar la información requerida para recuperar la instancia externa de alguna tienda, si no puede hacer que todas sean serializables. – Vikdor

0

Este es el responsib ilidad del JobFactory. La implementación predeterminada PropertySettingJobFactory invocará cualquier método de establecimiento de bean, en función de las propiedades encontradas en el contexto de schdeuler, el desencadenante y los detalles del trabajo. Así que, mientras usted ha implemnted un método setContext() colocador apropiada que debe ser capaz de hacer algo de lo siguiente:

scheduler.getContext().put("context", context); 

O

Trigger trigger = TriggerBuilder.newTrigger() 
    ... 
    .usingJobData("context", context) 
    .build() 

O

JobDetail job = JobBuilder.newJob(SimpleJob.class) 
    ... 
    .usingJobData("context", context) 
    .build() 

O si eso ISN No es suficiente que pueda proporcionar su propia clase JobFactory que ejemplifique los objetos de Job como lo desee.

0

Resuelva este problema creando una interfaz con un HashMap poniendo allí la información requerida.

Implemente esta interfaz en su clase Quartz Job, esta información será accesible.

En IFace

Map<JobKey,Object> map = new HashMap<>(); 

En Job

map.get(context.getJobDetail().getKey()) => will give you Object 
Cuestiones relacionadas