我正在使用Spring启动开发应用程序,我正在使用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;
我试图让runnable控制器(服务正确自动装配),但问题是一样的,因为我需要做new controller();
。
我已经阅读了这些帖子post 1 post 2,但任何解决方案都有效。
更新:我需要在新线程中运行任务,因为它将每X小时执行一次。该任务从Internet下载数据集并将其保存到数据库中。
如果您需要定期执行某项任务:
@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
}
}
如果我理解正确,您将尝试使用虚拟数据填充数据库。
此实用程序类创建一组A实体,然后将其存储到数据库中
你为什么使用Runnable
?这个任务是通过新的Thread
运行的吗?
如果没有,那么在你的@PostConstruct
里面使用@Controller
,它可以访问正确的@Service
。保证在完全构造Bean之后调用标记的方法,并且已满足其所有依赖项。
@PostConstruct
private void persistEntities() {
...
service.save(entities);
}
如果你使用Spring Boot,你可以在data-*.sql
下放置一个src/main/resources/
文件。它将在启动时运行。
正如@CoderinoJavarino在评论中所说,我需要使用可运行类的@Scheduled
实例。
按计划,Spring可以正确地自动连接服务。所以,最后,我的初始runnable实用程序类已成为一个预定的类。