当前位置: 代码迷 >> java >> @Autowired服务为空,但我需要创建新实例
  详细解决方案

@Autowired服务为空,但我需要创建新实例

热度:51   发布时间:2023-08-04 09:14:01.0

我正在使用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下载数据集并将其保存到数据库中。

如果我理解正确,则您正在尝试使用虚拟数据填充数据库。

该实用工具类创建一组A实体,然后将其存储到数据库中

为什么要使用Runnable 该任务是否通过新Thread运行?
如果没有,则在@Controller使用@PostConstruct ,该@Controller有权访问@Service 可以保证在Bean完全构造好并满足其所有依赖关系之后,才调用带标记的方法。

@PostConstruct
private void persistEntities() {
   ...
   service.save(entities);
}

如果您使用的是Spring Boot,则可以将data-*.sql文件放在src/main/resources/ 它将在启动时运行。

如果您需要定期执行一些任务:

@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
    }
}

就像@CoderinoJavarino在评论中说的那样,我需要使用可运行类的@Scheduled实例。

通过计划,Spring可以正确地自动连接服务。 因此,最后,我最初的可运行实用程序类变成了计划类。

  相关解决方案