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

时间:2019-02-22 18:14:45

标签: java spring-boot model-view-controller autowired runnable

我正在使用Spring Boot开发应用程序,正在使用MVC模型。 我有一个称为A的实体,它具有其控制器,服务和存储库。一切都在这里。

我有一个实用程序类,该类可运行并且在服务器启动时被调用。该实用程序类创建一组A实体,然后将其存储到数据库中。问题在于该类的autowired服务为空,因为我已经创建了一个实用程序类的新实例来运行它,因此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();

我已经阅读了这些帖子 post 1 post 2,但任何解决方案都可以。

更新:我需要任务在新线程中运行,因为它将每X个小时执行一次。该任务将从Internet下载数据集并将其保存到数据库中。

3 个答案:

答案 0 :(得分:0)

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

  

此实用程序类创建一组A实体,然后将其存储   进入数据库

您为什么要使用Runnable?此任务是否通过新的Thread运行?
如果不是,请在@PostConstruct内使用@Controller,它可以访问右边的@Service。保证已标记的方法在Bean完全构造好并且所有依赖项都得到满足之后被调用。

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

按照计划,Spring可以正确地自动连接服务。因此,最后,我最初的可运行实用程序类已成为计划的类。