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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49698963/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 03:05:49  来源:igfitidea点击:

How to call a service from Main application calls Spring Boot?

javaspringspring-boot

提问by Roland

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:

我正在构建一个将从命令行调用的 Spring Boot 应用程序。我将向应用程序传递一些参数,但在从此类调用服务时遇到问题:

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

采纳答案by shahaf

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

你可以在这里获得更多信息

回答by KenCoenen

By using the newkeyword yourself to create an instance of the Appclass, 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 ApplicationContextby letting your Appclass 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 Appinstance.

然后,您可以使用它来检索正确的App实例。

App myApp = (App) applicationContext.getBean(App.class);
myApp.myMethod()

Please note that accessing the ApplicationContextdirectly does kind of violate the whole dependency injection principle, but sometimes you haven't got much choice.

请注意,ApplicationContext直接访问确实违反了整个依赖注入原则,但有时您没有太多选择。

回答by Wojciech Wirzbicki

In SpringBoot 2.x you can simply run the application by SpringApplication.runmethod and operate on the returned ApplicationContext. Complete example below:

在 SpringBoot 2.x 中,您可以简单地通过SpringApplication.run方法运行应用程序并对返回的 ApplicationContext 进行操作。完整示例如下:

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));
    }
}