【问题标题】:Using @Autowired service in quartz job在石英作业中使用@Autowired 服务
【发布时间】:2020-08-28 00:13:54
【问题描述】:

我正在使用 Spring Boot,并且我有一项服务可以从 DB 中存储/检索一些数据。我想使用使用我的服务的石英作业。我尝试了互联网上的许多建议将石英与弹簧靴集成,但它不起作用。你能帮我吗?
这是我的代码:
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 作为我的服务的数据库:

服务器端口=8281 spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=我的用户名 spring.datasource.password=我的密码

3) 这是我的服务:

@服务 公共类报告服务{ jdbc模板 jdbc模板; 公共报告服务(JdbcTemplate jdbcTemplate){ this.jdbcTemplate = jdbcTemplate; } 公共列表 getPendingReports() { String sql = "SELECT * FROM report WHERE status = '" + ReportStatus.PENDING.name() +"'"; ReportMapper reportsMapper = new ReportMapper(); 列出报告 = jdbcTemplate.query(sql, reportsMapper); 返回报告; } }

4) 调度器类:

导入 org.quartz.JobBuilder; 导入 org.quartz.JobDetail; 导入 org.quartz.Scheduler; 导入 org.quartz.SchedulerException; 导入 org.quartz.SchedulerFactory; 导入 org.quartz.SimpleScheduleBuilder; 导入 org.quartz.SimpleTrigger; 导入 org.quartz.TriggerBuilder; 导入 org.quartz.impl.StdSchedulerFactory; 公共类 ReportScheduler { 公共无效scanAndUpdateReports(){ SchedulerFactory sf = new StdSchedulerFactory(); 尝试 { 调度器 scheduler = sf.getScheduler(); 调度程序.start(); JobDetail 作业 = JobBuilder.newJob(ReportsJob.class) .withIdentity("reportsJob") 。建造(); SimpleTrigger 触发器 = (SimpleTrigger) TriggerBuilder.newTrigger() .withIdentity("reportsTrigger") 。现在开始() .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(60).repeatForever()) 。建造(); scheduler.scheduleJob(作业,触发器); } 捕捉(SchedulerException e){ // TODO 自动生成的 catch 块 e.printStackTrace(); } } }

5) 以及我想要自动装配 ReportService 的作业类,但它为空:

公共类 ReportsJob 实现 Job { @自动连线 报告服务报告服务; //这不起作用(它为空) @覆盖 公共无效执行(JobExecutionContext 上下文)抛出 JobExecutionException { 列出报告 = reportService.getPendingReports(); System.out.println("报告:\n"+报告); } }

6) 现在我正在从 main 方法调用调度程序:

@SpringBootApplication 公共类 ReportAppBeApplication { 公共静态无效主要(字符串[]参数){ SpringApplication.run(ReportAppBeApplication.class, args); ReportScheduler rs = new ReportScheduler(); rs.scanAndUpdateReports(); } }

【问题讨论】:

标签: java spring-boot quartz-scheduler


【解决方案1】:

就我而言,我添加了注释 @DisallowConcurrentExecution 。之后,我就可以顺利访问自动连接的服务了。

import org.quartz.DisallowConcurrentExecution;

@DisallowConcurrentExecution
public class InvoiceJob implements Job {
   @Autowired
   private RuntimeConfigurationService runtimeConfigurationService;
}

【讨论】:

    【解决方案2】:

    它为空,因为@Autowired 仅适用于@Component@Repository@Service 注释类。 注释您的ReportJobclass 并确保您存储该类的地图包含在启动时的component scan 中。您可以包含用于扫描的地图:

    @ComponentScan(basePackages={"folderOfReportJob"})

    这个注解应该被添加到@Configuration@SpringBootApplication 被注解的类中。

    编辑:

    如果你不想让你的工作成为一个组件,你也可以通过ApplicationContext 类手动获取bean。它是这样的:

    private static ApplicationContext ac;
    ReportService reportService = ac.getBean(ReportService.class);
    

    【讨论】:

    • 我将作业类标记为@Component 它仍然显示reportService 的NullPointerException。我试过在我的包上使用@ComponentScan,还是一样。
    • 尝试使用ApplicationContext@ViorelCasapu
    猜你喜欢
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    相关资源
    最近更新 更多