[英]How to call a service from Main application calls Spring Boot?
I'm building a Spring Boot application that will be called from command line.我正在构建一个将从命令行调用的 Spring Boot 应用程序。 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:我正在尝试从 main 内部调用一个方法,但出现错误:
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)
you can create a class that implements CommandLineRunner and this will be invoked after the app will start您可以创建一个实现 CommandLineRunner 的类,这将在应用程序启动后调用
@Component
public class CommandLineAppStartupRunner implements CommandLineRunner {
@Autowired
private MyService myService;
@Override
public void run(String...args) throws Exception {
myService.save();
}
}
In SpringBoot 2.x you can simply run the application by SpringApplication.run
method and operate on the returned ApplicationContext.在 SpringBoot 2.x 中,您可以简单地通过
SpringApplication.run
方法运行应用程序并对返回的 ApplicationContext 进行操作。 Complete example below:完整示例如下:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import java.util.Arrays;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
SomeService service = applicationContext.getBean(SomeService.class);
service.doSth(args);
}
}
@Service
class SomeService {
public void doSth(String[] args){
System.out.println(Arrays.toString(args));
}
}
By using the new
keyword yourself to create an instance of the App
class, Spring cannot know about it.通过自己使用
new
关键字创建App
类的实例,Spring 无法知道它。
It's also redundant, as Spring automatically creates a bean instance of this class by a mechanism called component scan.这也是多余的,因为 Spring 通过称为组件扫描的机制自动创建此类的 bean 实例。
I like the solution of the CommandLineRunner
.我喜欢
CommandLineRunner
的解决方案。
What you also can do, is retrieve the ApplicationContext
, lookup the bean and then call the method.您还可以做的是检索
ApplicationContext
,查找 bean 然后调用该方法。
You can inject the ApplicationContext
by letting your App
class implement ApplicationContextAware
, override the setter method and save the context in a static variable which you can access from your main method.您可以注入
ApplicationContext
通过让您的App
类实现ApplicationContextAware
,覆盖setter方法和保存,你可以从你的主要方法访问静态变量的上下文。
Then, you can use it to retrieve the correct App
instance.然后,您可以使用它来检索正确的
App
实例。
App myApp = (App) applicationContext.getBean(App.class);
myApp.myMethod()
Please note that accessing the ApplicationContext
directly does kind of violate the whole dependency injection principle, but sometimes you haven't got much choice.请注意,直接访问
ApplicationContext
确实违反了整个依赖注入原则,但有时您没有太多选择。
The issue with your code is you didn't look up the applicationContext bean for the service Which you are using.您的代码的问题是您没有查找您正在使用的服务的 applicationContext bean。 I had a similar use case, to call a feature service on the startup of the application.
我有一个类似的用例,在应用程序启动时调用功能服务。 Initializing multiple applicationContext beans for the services and then making the method called works just fine!
为服务初始化多个 applicationContext bean,然后使调用的方法工作正常! Code below :
下面的代码:
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(UamRbacApplication.class, args);
AccessChangeSchedulerService accessChangeSchedulerService = applicationContext.getBean(AccessChangeSchedulerService.class);
AppContext appContext = applicationContext.getBean(AppContext.class);
try {
accessChangeSchedulerService.fetchAccessLevelChanges("EP", appContext.getSplunkToken());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
Cheers.干杯。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.