我正在建立一个需要根据请求网址在两组属性之间切换的网络服务。我不确定哪种方法最适合处理。
我有一个具有yaml属性文件的Spring Boot应用程序。在属性文件中,结构看起来像这样;
optionA:
foo:
urls:
- a
- b
bar:
something: hello
optionB:
foo:
urls:
- x
- y
bar:
something: bye
optionA
和optionB
几乎都具有相同的属性,只有不同的值。
所以请求进来,我检查请求并决定是否需要optionA或optionB。
我一直试图让@ConfigurationProperties
来处理这个问题,但这些属性会在启动时初始化,因此它不会是动态的。另一种可能性是我有两个配置类,每个选项一个但后来我的代码充满了检查以在两个类之间切换,这些类几乎完全相同,也不是很好。
任何有关如何最好地管理此事的最佳做法或建议都会受到赞赏,欢呼!
答案 0 :(得分:2)
如果您没有太多选择,我会这样做:(刚刚用较小的配置制作示例)
<强> options.yml:强>
optionA:
name: optionA
optionB:
name: optionB
我为扩展程序创建了一个Option类:
public class Option {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
设置@ConfigurationProperties
的两个Option类:(现在这些类都是空的,但您有机会对每个不同的选项更具体)
@Component
@ConfigurationProperties(prefix ="optionA", locations = "classpath:options.yml")
public class OptionA extends Option{
}
@Component
@ConfigurationProperties(prefix ="optionB", locations = "classpath:options.yml")
public class OptionB extends Option{
}
为了决定不同的选项,我创建了interface
:
public interface OptionService {
Option findOption(boolean businessLogic);
}
在实现中,我注入了两个选项和业务逻辑的实现:(以一种简单的方式)
@Service
public class OptionServiceImpl implements OptionService {
private OptionA optionA;
private OptionB optionB;
@Override
public Option findOption(boolean businessLogic) {
if(businessLogic){
return getOptionA();
} else {
return getOptionB();
}
}
public OptionA getOptionA() {
return optionA;
}
@Autowired
public void setOptionA(OptionA optionA) {
this.optionA = optionA;
}
public OptionB getOptionB() {
return optionB;
}
@Autowired
public void setOptionB(OptionB optionB) {
this.optionB = optionB;
}
}
最后,您的控制器只需拨打OptionServiceImpl
课程,并取消使用哪个选项:
@Controller
public class YourController {
private OptionService optionServiceImpl;
@RequestMapping("/")
public String getIndex(){
Option option = getOptionServiceImpl().findOption(true);
System.out.println(option.getName());
option = getOptionServiceImpl().findOption(false);
System.out.println(option.getName());
return "Hello World";
}
public OptionService getOptionServiceImpl() {
return optionServiceImpl;
}
@Autowired
public void setOptionServiceImpl(OptionService optionServiceImpl) {
this.optionServiceImpl = optionServiceImpl;
}
}
System.out.println的输出:
optionA
optionB
因此,决定应该使用哪个选项的业务逻辑不是if-else结构。您可以在界面及其实现中为decission创建规则。我认为您可以为更多控制器创建更多规则。
答案 1 :(得分:0)
您可以在application.properties中定义键值对。
其中key是Web服务名称,value是选项(属性列表)
使用@ConfigurationProperties
@ConfigurationProperties
class Configuration {
Map<String,Option> options;
// getters and setters
}
@Component
class ChooseServiceBasedConfiguration {
@Autowired
Configuration configuration;
public void serviceMethod(String key ){
//get appropriate properties of the web service
configuration.getOptions().get(key);
}
}
基于Web服务,使用密钥获取所需的值。
答案 2 :(得分:0)
将您的yml更改为:
options:
- name: optionA
foo:
urls:
- a
- b
bar:
something: hello
- name: optionB
foo:
urls:
- x
- y
bar:
something: bye
添加Config类:
@Data
@ConfigurationProperties
@Configuration
public class MyConfig {
private List<Option> options;
}
使用它:
@Component
public class UseConfig {
@Autowired
public UseConfig(final MyConfig config) {
System.out.println(config.getOptions());
}
}
结果:
[Option(name=optionA, foo=Foo(urls=[a, b]), bar=Bar(something=hello)), Option(name=optionB, foo=Foo(urls=[x, y]), bar=Bar(something=bye))]