简体   繁体   English

如何从主应用程序调用服务调用 Spring Boot?

[英]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();

    }
}

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.在 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.

相关问题 如何从 Spring Boot 调用 SOAP 服务 - How to call SOAP service from Spring boot 如何从spring boot服务层调用java类方法 - How to call a java class method from spring boot service layer 在Spring Boot中如何从实体类中调用基于服务的类 - How to call service based classes from entity class in spring boot 如何从 Spring Boot 应用程序的文件夹作为 jar 运行主应用程序(不是 Spring Boots 应用程序) - How to run a main application (not a spring boots appl) from a folder of Spring Boot application as jar 如何从Spring Boot应用程序调用HTML页面 - how to call a html page from spring boot application 如何从spring boot应用程序调用oracle函数? - How to call oracle function from spring boot application? Spring Boot - 如何仅通过提供的服务类名称从服务类调用方法? - Spring Boot - How to call method from a service class just by the provided service class name? 如何测试 Spring-boot 应用程序的主类 - How to test main class of Spring-boot application 如何在Spring Boot应用程序的main方法中正确初始化Bean? - How to correctly initialise a Bean in the main method of a Spring Boot application? 我应该测试Spring Boot Application的main()方法以及如何? - Should I test the main() method of Spring Boot Application and how?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM