Search code examples
javaspring-bootmodel-view-controllerautowiredrunnable

@Autowired service is null but I need create new instance


I'm developing an app with Spring boot, I'm using the MVC model. I have an entity called A, which has its controller, service and repository. all right up here.

I have an utility class, which is runnable and is called when the server start. This utility class create a set of A entities, and then, stored it into database. The problem is that the autowired service of the class is null, because I have created a new instance of the utility class in order to run it, so Spring doesn't create the autowired service correctly.

that is:

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
}

I know that Spring cannot autowired the service of this new instance, but I need to create the utility instance in order to run it.

I have tried to access to the service through application context, but the problem is the same:

 @Autowired 
 private ApplicationContext applicationContext;

I have tried to make runnable the controller (where the service is autowired correctly), but the problem is the same, since I need to do the new controller();.

I have read these posts post 1 post 2, but any solution works.

UPDATE: I need that the task run in a new thread, since it will be executed each X hours. The task downloads a data set from Internet and save it into database.


Solution

  • If you need to do some task periodically:

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