如何在运行时管理两组属性?

8 java spring spring-boot

我正在构建一个需要在两组属性之间切换的Web服务,具体取决于请求URL的进入.我不确定哪种方法最好.

我有一个Spring Boot应用程序,它有一个yaml属性文件.在属性文件中,结构看起来像这样;

optionA:
  foo:
    urls:
      - a
      - b
  bar:  
    something: hello

optionB:
  foo:
    urls:
      - x
      - y
  bar:  
    something: bye
Run Code Online (Sandbox Code Playgroud)

双方optionAoptionB拥有几乎所有相同的属性,只是不同的价值观.

所以请求进来,我检查请求并决定是否需要optionA或optionB.

我一直试图@ConfigurationProperties处理这个问题,但属性是在启动时初始化的,所以它不能是动态的.另一种可能性是我有两个配置类,每个选项一个但后来我的代码充满了检查以在两个类之间切换,这些类几乎完全相同,也不是很好.

关于如何最好地管理这个的任何最佳实践或建议将不胜感激,欢呼!

Pat*_*ick 2

如果你没有太多选择,我会这样做:(只是用较小的配置制作了示例)

选项.yml:

optionA:
  name: optionA
optionB:
  name: optionB
Run Code Online (Sandbox Code Playgroud)

我创建了一个用于扩展的 Option 类:

public class Option {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

@ConfigurationProperties以及两个正在设置的选项类:(目前这些类是空的,但您有机会更具体地了解每个不同的选项)

@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{
}
Run Code Online (Sandbox Code Playgroud)

为了决定不同的选项,我创建了一个interface

public interface OptionService {

    Option findOption(boolean businessLogic);
}
Run Code Online (Sandbox Code Playgroud)

在实现中,我注入了选项和业务逻辑的实现:(以简单的方式)

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,您的控制器只需调用该类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;
    }
}
Run Code Online (Sandbox Code Playgroud)

System.out.println 的输出:

optionA
optionB
Run Code Online (Sandbox Code Playgroud)

因此,决定应使用哪个选项的业务逻辑不是 if - else 构造。您可以在接口及其实现中创建决策规则。我认为您可以为更多控制器创建更多规则。