问题描述
我正在使用Spring Boot开发应用程序,正在使用MVC模型。 我有一个称为A的实体,它具有其控制器,服务和存储库。 一切都在这里。
我有一个实用程序类,该类可运行并且在服务器启动时被调用。
该实用程序类创建一组A实体,然后将其存储到数据库中。
问题是该类的autowired
服务为null,因为我已经创建了一个实用程序类的新实例以运行它,因此Spring不能正确创建自动装配服务。
那是:
Main.java
@SpringBootApplication
public class MainClass {
public static void main(String[] args) {
...
Runnable task = new Utility();
...
}
}
Utility.java
@Autowired
private Service service;
...
public void run() {
...
service.save(entities); <-- NPE
}
我知道Spring无法自动连接该新实例的服务,但是我需要创建实用程序实例才能运行它。
我试图通过应用程序上下文访问服务,但是问题是相同的:
@Autowired
private ApplicationContext applicationContext;
我试图使可运行的控制器(正确连接服务的位置)可运行,但是问题是相同的,因为我需要执行new controller();
。
我已经阅读了这些帖子 ,但是任何解决方案都可以。
更新:我需要任务在新线程中运行,因为它将每X个小时执行一次。 该任务从Internet下载数据集并将其保存到数据库中。
1楼
如果我理解正确,则您正在尝试使用虚拟数据填充数据库。
该实用工具类创建一组A实体,然后将其存储到数据库中
为什么要使用Runnable
?
该任务是否通过新Thread
运行?
如果没有,则在@Controller
使用@PostConstruct
,该@Controller
有权访问@Service
。
可以保证在Bean完全构造好并满足其所有依赖关系之后,才调用带标记的方法。
@PostConstruct
private void persistEntities() {
...
service.save(entities);
}
如果您使用的是Spring Boot,则可以将data-*.sql
文件放在src/main/resources/
。
它将在启动时运行。
2楼
如果您需要定期执行一些任务:
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application .class, args);
}
}
@Component
class Runner {
@Autowired
private Service service;
@Scheduled(cron = "0 */2 * * * ?") // execute every 2 hours
public void run() {
// put your logic here
}
}
3楼
就像@CoderinoJavarino在评论中说的那样,我需要使用可运行类的@Scheduled
实例。
通过计划,Spring可以正确地自动连接服务。 因此,最后,我最初的可运行实用程序类变成了计划类。