是否有一种方法可以在Spring Boot中基于命令行参数注入特定的接口实现?
我有一个数据加载应用程序,根据命令行参数,我需要加载特定类型的数据。
这是我的主要课程,CommandLineRunner
:
@SpringBootApplication
public class DataLoadersApplication implements CommandLineRunner {
private Type1LoadProcess type1LoadProcess;
private Type2LoadProcess type2LoadProcess;
public DataLoadersApplication(Type1LoadProcess type1LoadProcess,
Type2LoadProcess type2LoadProcess) {
this.type1LoadProcess = type1LoadProcess;
this.type2LoadProcess = type2LoadProcess;
}
public static void main(String[] args) {
SpringApplication.run(DataLoadersApplication.class, args);
}
@Override
public void run(String... args) {
if (args[0].equalsIgnoreCase("load-type1")) {
type1LoadProcess.process();
} else if (args[0].equalsIgnoreCase("load-type2")) {
type2LoadProcess.process();
}
}
}
有没有一种方法,我可以创建带有两个实现DataLoadeProcess
和Type1DataLoadProcess
的{{1}}接口,并根据命令行arg将实现插入主类?
答案 0 :(得分:5)
您可以使用Spring概要文件来实现您的目标: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html
创建接口DataLoadProcess
然后上课:
@Component
@Profile("type1")
public class Type1LoadProcess implements DataLoadProcess {
}
@Component
@Profile("type2")
public class Type2LoadProcess implements DataLoadProcess {
}
然后,您可以注入以下接口类型:
@Autowired
DataLoadProcess dataLoadProcessor;
现在您可以使用其中一个配置文件启动应用程序,例如,设置系统属性:
-Dspring.profiles.active=type1
答案 1 :(得分:2)
为此,我将使用Spring profiles。只需将您的实现转换为Spring Bean,然后基于活动配置文件加载所需的Bean。
然后在启动应用程序时将活动配置文件指定为命令行参数时,应使用相应的Bean。
答案 2 :(得分:2)
一个完整的例子是
@SpringBootApplication
public class DataLoadersApplication implements CommandLineRunner {
public interface LoadProcess {
void doLoad();
}
@Component // default that exists unconditionally in any profile
static class Type1LoadProcess implements LoadProcess {
@Override public void doLoad() { System.out.println("Load1"); }
}
@Profile("type2") // this only exists in the type2 profile
@Primary // if it exists it gets picked over others
@Component
static class Type2LoadProcess implements LoadProcess {
@Override public void doLoad() { System.out.println("Load2"); }
}
// need a 3rd? @Profile("type3") @Primary @Component
@Autowired // need one of them here
private LoadProcess loadProcess;
@Override
public void run(String... args) {
loadProcess.doLoad();
}
public static void main(String[] args) {
SpringApplication.run(DataLoadersApplication.class, args);
}
}
这会利用配置文件,并使用主bean机制在未指定配置文件时允许默认实现。
然后您可以通过https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html中列出的任何选项来选择使用哪个配置文件,例如通过设置环境变量
SPRING_PROFILES_ACTIVE=type2 java -jar myApp.jar
使用属性
java -Dspring.profiles.active=type2 java -jar myApp.jar
甚至一个参数
java -jar myApp.jar --spring.profiles.active=type2
当您需要type2实现时。即使没有定义,您仍然可以将“ type1”作为活动配置文件。它将仍然是正确的事情,并使用type1代码,因为这是默认设置。