Spring Boot 传递局部变量

SpringBoot pass local variable

我正在创建一个 Java 应用程序,它根据某些 conditions/configurations 它实例化一个 SpringBoot 应用程序来接收一些 HTTP 消息。

我的问题是我有一个 ReceiverService 需要使用一些在 SpringBoot 应用程序之外创建的变量。 有没有办法将本地 java 变量(从应用程序内部,而不是像 shell 或文件那样)传递给 SpringBoot 组件?

示例:

我有一个 Manager 对象,根据某些条件,它定义了一个我想在 SpringBoot 组件 ReceiverService.

中使用的变量 param
public class Manager {

    public Manager(bool condition) {
         String param = "foo";
         if (condition) {
             param = "bar";
         }
         
         ReceiverApp receiver = new ReceiverApp(); // init SpringBoot app
    }
}

SpringBoot 应用程序:

@SpringBootApplication
public class ReceiverApp {

    public ReceiverApp() {

        SpringApplication.run(ReceiverApp.class);
    }
@Component
public class ReceiverService implements InitializingBean {

    final CustomObject obj1 = new CustomObject(param);

    @Override
    public void aFunction() throws Exception {
        MyConfig config = MyConfig.build(param);
    }
}

您可以让 ReceiverService 注入一个 Supplier<String>(或者如果您喜欢不太通用的命名,则定义您自己的接口)并让 Manager 实现它。

@Component
public class ReceiverService implements InitializingBean {
    @Autowired
    private Supplier<String> paramSupplier;

    final CustomObject obj1 = new CustomObject(param);

    @Override
    public void aFunction() throws Exception {
        MyConfig config = MyConfig.build(paramSupplier.get());
    }
}

public class Manager implements Supplier<String> {
    private final String param;
    public String get() { return param; }

    public Manager(bool condition) {
         param = "foo";
         if (condition) {
             param = "bar";
         }
         
         // why is this in the Manager constructor???
         ReceiverApp receiver = new ReceiverApp(); // init SpringBoot app
    }
}

或者您定义自己的@Component 来提供参数并让管理器和接收器都注入它。

SpringApplication.run 旨在接受键=值对,就像您在 Java.

中的主要方法的命令行参数中提供的那样

由于您的 class-path 中似乎有另一个 Spring 引导应用程序 jar,并且似乎能够实例化 ReceiverApp,您可以将参数作为字符串传递(格式 String[]{"key1=value1", "key2=value2"})

这些可以传递给 SpringApplication.run,这些将自动成为 Spring 配置值,可以在应用程序的任何地方注入。

@SpringBootApplication
public class ReceiverApp {

    public ReceiverApp(String[] notReallyFromCommandLineArgs) {

        SpringApplication.run(ReceiverApp.class, notReallyFromCommandLineArgs);
    }

您可以这样发送参数:

String[] params = new String[]{"my.params.param1="+param1};
ReceiverApp receiver = new ReceiverApp(params);

您可以将它们作为值注入 Receiver Spring 应用程序的任何位置。

@Value("my.params.param1")
String theParam1;

参考:

有多种方法可以创建配置另一个应用程序的管理器应用程序。

场景一

一种常见的方法是将配置放在两个应用程序都可以直接访问的数据库中,尽管这样不太干净(它通过数据库创建了硬依赖性)。

场景二

一个更简洁的解决方案是,如果管理器应用程序拥有数据库,并提供配置服务,该配置服务由配置的应用程序使用(并且可能缓存)。通常,配置服务将通过远程处理访问,例如REST,因此可以独立部署和 运行 这两个应用程序。

场景三

如果您想保持简单,您可以反转设置并在配置的应用程序本身中实现配置服务(有点像 Tomcat 中的管理界面)。然后你可以在同一个应用程序中添加一个 web UI 并完成它,或者构建一个单独的独立客户端来与该服务交互。在最后两个场景中,请考虑安全性,因为您可能不希望任何客户端能够连接和更改配置。