Как добавить свойства в контекст приложения spring boot во время выполнения

#java #spring #spring-boot #properties

#java #spring #spring-boot #свойства

Вопрос:

У меня есть приложение Spring boot и файл свойств, config.properties где значения зашифрованы (пожалуйста, смотрите Пример ниже)

 config.properties

myapp.property1={5AES123}SafeR70/wqqwwqwqwqwqsdaWQmNs O2afeIU/1MHoCWvTgxUYA30C/rrei4=
myapp.property2={5AES342}MareV70/PLNqsasasaa*ksueoHH O2afeIU/1MHoCWvTgxUYJQ30C/7rei4=
myapp.property3={5AES111}TutoV10/xdtghshI5CVULQ7uevr O2afeIU/1MHoCWvTgxUYJQ30C/1rei4=
  

Я использую специальный API (добавленный как зависимость от POM в моем приложении) для расшифровки этих значений.

Пожалуйста, найдите ниже ПСЕВДОКОД, чтобы лучше объяснить мои намерения и то, что я хотел бы иметь в конце дня.

 public static void main(String[] args) {

  // 1. decrypt the properties values of the config.properties using my special API package.
  List<MyPropDecrypted> myPropDecryptedLst = mySpecialAPIPack.decrpyt("config.properties");

  // 2. get the spring context
  myAppSpringContext = getSpringContext();

  //3. add the decrypted properties to the spring context from step 2.
  int idx = 0;
  for (MyPropDecrypted myPropDecrypted : myPropDecryptedLst){
     idx  ;
     myAppSpringContext.setProperty("myapp.property" idx, myPropDecrypted.getDecrypteValue();
  }

  SpringApplication.run(Application.class, args);
}
  

Мой вопрос в том, как я могу программно добавить / внедрить эти расшифрованные (с помощью моего специального API) свойства в контекст spring, чтобы я мог использовать его как свойства, загруженные из файла свойств (@Value(«${myapp.property1}»))?

Ответ №1:

Вы могли бы использовать Spring Cloud Config и реализовать пользовательский компонент EnvironmentRepository, как описано здесь:

Пользовательские репозитории составной среды В дополнение к использованию одного из репозиториев среды из Spring Cloud, вы также можете предоставить свой собственный компонент EnvironmentRepository, который будет включен как часть составной среды. Для этого ваш компонент должен реализовать интерфейс EnvironmentRepository. Если вы хотите управлять приоритетом вашего пользовательского EnvironmentRepository в составной среде, вам также следует реализовать упорядоченный интерфейс и переопределить метод getOrdered. Если вы не реализуете упорядоченный интерфейс, вашему EnvironmentRepository присваивается наименьший приоритет.

Документы

Ответ №2:

Я бы посоветовал вам создать класс конфигурации, подобный этому :

  @ConfigurationProperties
    @Configuration
    class MyConfig{
    
   public Map<String,String > myapp;
    
     public String getproperty1() {
      return myapp.get("property1");
    }
    
      public String getProperty2() {
    //
    }
    
    //getters and setter for all the three properties
    
    }
  

Теперь обновите свой псевдокод, чтобы установить расшифрованные значения, используя методы setter. Затем вы можете внедрить класс MyConfig в любой другой класс и получить значения.

Комментарии:

1. Это очень хорошая идея, и я думаю, что я воспользуюсь ею в конце дня. Было бы идеально вместо этого иметь оба (комбинацию обоих, конфигурации и значения). Допустим, во время выполнения spring, чтобы иметь возможность настраивать эти значения с помощью конфигурации и делать эти свойства доступными для Value (${myprop1}).

2. Моим намерением было найти способ получить эти значения, не автоматически подключая MyConfig в каждом классе, мне нужны эти значения, но пусть Value (${…}) выполняет эту работу автоматически. Это потому, что я стараюсь избегать изменения завершающих классов, которые получают значения свойств по значению (${…})