I'm building a Spring Boot application that will be called from command line. I will pass to application some parameters but I'm having problems to call a service from this class:
@SpringBootApplication
public class App{
public static void main(String[] args) {
SpringApplication.run(App.class, args);
App app = new App();
app.myMethod();
}
@Autowired
private MyService myService;
private void myMethod(){
myService.save();
}
}
I'm trying to call a method from inside the main but I'm getting the error:
Exception in thread "main" java.lang.NullPointerException
at com.ef.Parser.App.myMethod(Application.java:26)
at com.ef.Parser.App.main(Application.java:18)
By using the
new
keyword yourself to create an instance of theApp
class, Spring cannot know about it.It's also redundant, as Spring automatically creates a bean instance of this class by a mechanism called component scan.
I like the solution of the
CommandLineRunner
.What you also can do, is retrieve the
ApplicationContext
, lookup the bean and then call the method.You can inject the
ApplicationContext
by letting yourApp
class implementApplicationContextAware
, override the setter method and save the context in a static variable which you can access from your main method.Then, you can use it to retrieve the correct
App
instance.Please note that accessing the
ApplicationContext
directly does kind of violate the whole dependency injection principle, but sometimes you haven't got much choice.you can create a class that implements CommandLineRunner and this will be invoked after the app will start
you can get farther information on this here
In SpringBoot 2.x you can simply run the application by
SpringApplication.run
method and operate on the returned ApplicationContext. Complete example below: