[英]Using @Autowired service in quartz job
我正在使用 spring 引导,并且我有一项服务可以从数据库存储/检索一些数据。 我想使用使用我的服务的石英作业。 我尝试了许多来自互联网的建议,将石英与 spring 引导集成,但它不起作用。 你能帮我吗?
这是我的代码:
1)我在 pom.xml 中添加了 org.quartz-scheduler 作为依赖项:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
</dependencies>
2)这是我的 application.properties 配置为使用 mysql 作为我的服务的数据库:
server.port=8281 spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=myusername spring.datasource.password=mypassword
3)这是我的服务:
@Service public class ReportService { JdbcTemplate jdbcTemplate; public ReportService(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public List getPendingReports() { String sql = "SELECT * FROM report WHERE status = '" + ReportStatus.PENDING.name() +"'"; ReportMapper reportsMapper = new ReportMapper(); List reports = jdbcTemplate.query(sql, reportsMapper); return reports; } }
4)调度器class:
import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.SimpleScheduleBuilder; import org.quartz.SimpleTrigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; public class ReportScheduler { public void scanAndUpdateReports() { SchedulerFactory sf = new StdSchedulerFactory(); try { Scheduler scheduler = sf.getScheduler(); scheduler.start(); JobDetail job = JobBuilder.newJob(ReportsJob.class) .withIdentity("reportsJob") .build(); SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger() .withIdentity("reportsTrigger") .startNow() .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(60).repeatForever()) .build(); scheduler.scheduleJob(job, trigger); } catch (SchedulerException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
5)我的工作 class 我想自动连接 ReportService,但它是 null:
public class ReportsJob implements Job { @Autowired ReportService reportService; //this doesn't work (it is null) @Override public void execute(JobExecutionContext context) throws JobExecutionException { List reports = reportService.getPendingReports(); System.out.println("Reports:\n"+reports); } }
6)现在我正在从 main 方法调用调度程序:
@SpringBootApplication public class ReportAppBeApplication { public static void main(String[] args) { SpringApplication.run(ReportAppBeApplication.class, args); ReportScheduler rs = new ReportScheduler(); rs.scanAndUpdateReports(); } }
它是 null 因为@Autowired
仅适用于@Component
、 @Repository
或@Service
注释的 class。 注释您的ReportJob
class 并确保存储 class 的 map 包含在启动时的component scan
中。 您可以使用 map 进行扫描:
@ComponentScan(basePackages={"folderOfReportJob"})
此注解应添加到@Configuration
或@SpringBootApplication
注解的 class 中。
编辑:
如果你不想让你的工作成为一个组件,你也可以通过ApplicationContext
class 手动获取 bean。 它是这样的:
private static ApplicationContext ac;
ReportService reportService = ac.getBean(ReportService.class);
我碰巧找到了一个关于功能实现的中文博客。 我可以说您正在尝试实现类似spring-boot-starter-quartz
东西。
总而言之,您应该定义自己的QuartzJobFactory
来修改createJobInstance
方法,将autowireBean
添加到新创建的 JobDetail 实例。
就像是,
JobDetail job = JobBuilder.newJob(ReportsJob.class)
.withIdentity("reportsJob")
.build();
// Pseudocode here
autowiredBean(job);
工作示例,
@Component("quartzJobFactory")
public static class QuartzJobFactory extends AdaptableJobFactory {
private final AutowireCapableBeanFactory capableBeanFactory;
public QuartzJobFactory(AutowireCapableBeanFactory capableBeanFactory) {
this.capableBeanFactory = capableBeanFactory;
}
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//调用父类的方法,把Job注入到spring中
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
@Configuration
class Configuration {
@Bean(name = "scheduler")
public Scheduler scheduler(QuartzJobFactory quartzJobFactory) throws Exception {
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
factoryBean.setJobFactory(quartzJobFactory);
factoryBean.afterPropertiesSet();
Scheduler scheduler = factoryBean.getScheduler();
scheduler.start();
return scheduler;
}
}
就我而言,我添加了注释@DisallowConcurrentExecution。 之后,我可以顺利访问自动接线服务。
import org.quartz.DisallowConcurrentExecution;
@DisallowConcurrentExecution
public class InvoiceJob implements Job {
@Autowired
private RuntimeConfigurationService runtimeConfigurationService;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.