2017-01-05 16 views
8

Tôi đang xây dựng một dịch vụ web cần phải chuyển đổi giữa hai bộ thuộc tính tùy thuộc vào URL yêu cầu sắp tới. Tôi không chắc đó là phương pháp xử lý tốt nhất điều này.Làm cách nào để quản lý hai bộ thuộc tính trong thời gian chạy?

Tôi có ứng dụng Khởi động mùa xuân có tệp thuộc tính yaml. Bên trong tập tin thuộc tính cấu trúc trông giống như thế này;

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

optionB: 
    foo: 
    urls: 
     - x 
     - y 
    bar: 
    something: bye 

Cả hai optionAoptionB có khá nhiều thuộc tính giống nhau, chỉ các giá trị khác nhau.

Vì vậy, yêu cầu đến, tôi kiểm tra yêu cầu và quyết định xem tôi có cần tùy chọnA hoặc tùy chọnB hay không.

Tôi đã cố gắng để có được @ConfigurationProperties để xử lý điều này nhưng các thuộc tính được khởi tạo khi khởi động để nó không thể động. Một khả năng khác là tôi có hai lớp cấu hình, một cho mỗi tùy chọn nhưng sau đó mã của tôi có đầy đủ các kiểm tra để chuyển đổi giữa hai lớp và các lớp là khá giống hệt nhau, không thực sự tốt đẹp hoặc.

Bất kỳ thực tiễn hay đề xuất nào tốt nhất về cách quản lý tốt nhất điều này sẽ được đánh giá cao, chúc mừng!

Trả lời

1

Nếu bạn chưa có quá nhiều lựa chọn tôi sẽ đi theo cách này: (Chỉ cần làm ví dụ với cấu hình nhỏ hơn)

tùy chọn.yml:

optionA: 
    name: optionA 
optionB: 
    name: optionB 

Tôi tạo ra một lớp Option cho phần mở rộng:

public class Option { 

    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

Và hai lớp Lựa chọn nơi @ConfigurationProperties đang nhận được thiết lập: (Còn bây giờ các lớp này là trống nhưng bạn phải cơ hội để cụ thể hơn về từng tùy chọn khác nhau)

@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{ 
} 

Đối với các quyết định của các tùy chọn khác nhau tôi đã tạo một interface:

public interface OptionService { 

    Option findOption(boolean businessLogic); 
} 

Và trong việc thực hiện tôi tiêm cả hai lựa chọn và thực hiện các logic kinh doanh: (một cách dễ dàng)

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

Và ở cuối bộ điều khiển, bạn chỉ cần gọi lớp OptionServiceImpl và đánh lừa tùy chọn nào nên được sử dụng:

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

Sản lượng System.out.println:

optionA 
optionB 

Vì vậy, logic kinh doanh của bạn để quyết định lựa chọn nên được sử dụng không phải là một nếu - khác xây dựng. Bạn có thể tạo ra các quy tắc cho sự phân chia trong giao diện và việc thực thi nó. Tôi nghĩ rằng bạn có thể tạo thêm quy tắc cho nhiều bộ điều khiển hơn.

+0

Cảm ơn, điều này về cơ bản là những gì tôi đã thực hiện trước khi đăng bài, cảm thấy một chút hack với các lớp chú thích trống nhưng nó hoạt động vì vậy tôi sẽ không lãng phí thời gian nữa trên haha ​​này – pquill

0

Bạn có thể xác định cặp giá trị khóa trong application.properties.

nơi quan trọng là tên dịch vụ web và giá trị là tùy chọn (danh sách các tài sản)

Make sử dụng @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); 
    }  
} 

dựa trên dịch vụ web được các giá trị cần sử dụng chìa khóa.

+0

Tôi không thể chạy ví dụ của bạn. Bạn có thể mô tả những gì bạn có nghĩa là với 'xác định cặp giá trị quan trọng trong application.properties'? –

+0

@WaleryStrauch Tôi định xác định các cặp khóa giá trị như đã đề cập trong ví dụ này https://dzone.com/articles/spring-boot-configurationproperties-1. Dựa trên các thuộc tính tương ứng quan trọng có thể lấy từ bản đồ – Barath

0

Thay đổi yml của bạn để:

options: 
    - name: optionA 
    foo: 
     urls: 
     - a 
     - b 
    bar: 
     something: hello 
    - name: optionB 
    foo: 
     urls: 
     - x 
     - y 
    bar: 
     something: bye 

Thêm Config lớp:

@Data 
@ConfigurationProperties 
@Configuration 
public class MyConfig { 

    private List<Option> options; 
} 

Sử dụng nó:

@Component 
public class UseConfig { 

    @Autowired 
    public UseConfig(final MyConfig config) { 
     System.out.println(config.getOptions()); 
    } 

} 

Kết quả:

[Option(name=optionA, foo=Foo(urls=[a, b]), bar=Bar(something=hello)), Option(name=optionB, foo=Foo(urls=[x, y]), bar=Bar(something=bye))] 
Các vấn đề liên quan