【问题标题】:Micronaut: Unable to inject a bean inside Quartz jobMicronaut:无法在 Quartz 作业中注入 bean
【发布时间】:2020-07-05 12:34:09
【问题描述】:

我正在尝试在 Quartz Job 实现的类中注入 bean(数据访问 GORM 服务或任何其他 bean),但它总是显示为 null。相同的 bean(GORM 或其他 bean)能够在其他类中注入而不会出现任何问题。 你能帮我检索这个 Job 类中的任何 bean。

我的石英工作

@Singleton
@Slf4j
class MyQuartzJob implements Job {

    @Inject
    MyHttpBean myHttpBean // unable to inject

    @Inject
    ApplicationContext appContext // unable to inject

    @Inject
    MyGORMService     myGormService // unable to inject
}

@Singleton
@Slf4j
class MyHttpBean {
// business logic
}

调用 QuartzJob 的代码

@Singleton
@Context
@Slf4j
@CompileStatic
class MasterScheduler{

     @PostConstruct
     void init(){
       // Quartz Job initialization code written here. This works fine.
     }
}

我的 build.gradle

dependencyManagement {
    imports {
        mavenBom 'io.micronaut:micronaut-bom:1.3.2'
    }
}

dependencies {
    annotationProcessor("io.micronaut:micronaut-inject-java:1.3.2")
    annotationProcessor("io.micronaut:micronaut-inject-groovy:1.3.2")
    implementation("io.micronaut:micronaut-inject:1.3.2")
  
    // https://mvnrepository.com/artifact/org.quartz-scheduler/quartz
    compile group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.0'

     ... other dependencies
}

Java version: 1.8

注意:我正在使用 Micronaut 调度功能,但我需要分布式执行支持,因此转向 Quartz ...

【问题讨论】:

  • 在您的应用程序中,是什么创建了MyQuartzJob 的实例?
  • 谢谢@JeffScottBrown,我正在使用以下方法。 JobDetail myJob = JobBuilder.newJob(MyJob.class).build() Trigger myTrigger = TriggerBuilder.newTrigger(). withIdentity('someidentity'). withSchedule(CronScheduleBuilder.cronSchedule('0 0/1 * 1/1 * ? *')).build() Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler() scheduler.start() scheduler.scheduleJob(myJob, myTrigger)

标签: groovy micronaut


【解决方案1】:

你需要定义一个 JobFactory。

package io.micronaut.quartz;

import io.micronaut.context.BeanContext;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Singleton;

@Singleton
public class MicronautJobFactory implements JobFactory {
    private final Logger log = LoggerFactory.getLogger(getClass());

    private final BeanContext beanContext;

    public MicronautJobFactory(BeanContext beanContext) {
        this.beanContext = beanContext;
    }

    @Override
    public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
        JobDetail jobDetail = bundle.getJobDetail();
        Class<? extends Job> jobClass = jobDetail.getJobClass();
        try {
            if (log.isDebugEnabled()) {
                log.debug(
                    "Producing instance of Job '" + jobDetail.getKey() +
                        "', class=" + jobClass.getName());
            }
            return beanContext.getBean(jobClass);
        } catch (Exception e) {
            SchedulerException se = new SchedulerException(
                "Problem instantiating class '"
                    + jobDetail.getJobClass().getName() + "'", e);
            throw se;
        }
    }
}

之后,当您定义调度程序时,您必须在定义时将您的工厂构建器添加到石英调度程序。这将替换 Quartz 附带的默认构建器。

您未来的所有工作都必须使用@Prototype 或@Singleton 注释来定义。默认情况下,Quartz 使用 newInstance() 来规避 Micronaut 定义的对象,但这会在声明作业时将对象构建推迟到 Micronaut。

scheduler.setJobFactory(jobFactory);

【讨论】:

    猜你喜欢
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    相关资源
    最近更新 更多