[英]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.