Я пытаюсь выяснить, как загрузить все классы конфигурации в пакет и сохранить его на карте.Эта карта будет передана в другие сервисы для получения их конфигураций.Каждый пакет представляет собой отдельную среду, и каждый класс конфигурации извлекается из отдельного файла yml.
Это похоже на область, отражение которой может быть полезно.Возьмите классы из-под пакета и создайте новый экземпляр каждого и сохраните его на карту.Было предложено, чтобы я взглянул на java classLoaders.Я новичок в размышлениях и загрузчиках классов.
(структура приложения)
src/main/java/com.example.demo
|
-- configs
| - KConfigurations
|
-- properties
| - dev
| - A1DevProperty
| - B1DevProperty
| - PropertyConfig
|
-- DemoApplication
|
-- resources
- application.yml
- application-a1-dev.yml
- application-b1-dev.yml
application.yml
spring:
application: test-application
profiles:
include:
- a1-dev
- b1-dev
application-a1.yml
a1-dev:
evn: dev
name: testing-a1-dev
. / Poperties / PropertyConfig(базовый класс)
@Configuration
public class PropertyConfig {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "PropertyConfig{" +
"name='" + name + '\'' +
'}';
}
}
. / poperties / dev / A1DevProperty
@Configuration
@ConfigurationProperties(prefix = "a1-dev")
public class A1DevProperty extends PropertyConfig {
}
. / configs / KConfigurations
@Component
public class KConfigurations {
private final static Logger LOG = LoggerFactory.getLogger(KConfigurations.class);
Map<String, PropertyConfig> kConfigurations;
List<Class> myProperties;
Reflections reflections;
public KConfigurations() {
this(new HashMap<String, PropertyConfig>(), new ArrayList<>());
}
public KConfigurations(Map<String, PropertyConfig> kConfigurations, List<Class> myProperties) {
this.kConfigurations = kConfigurations;
this.myProperties = myProperties;
this.reflections = new Reflections("com.example.demo.properties.dev");
}
public String loadKConfigurations(){
for(String propertyName :reflections.getStore().get(SubTypesScanner.class.getSimpleName()).values()){
try {
myProperties.add(Class.forName(propertyName));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
LOG.info("Property Name : {}", myProperties.toString());
LOG.info("Property type : {}", myProperties.get(0).getCanonicalName());
ClassLoader classLoader = this.getClass().getClassLoader();
try {
Class loadedMyClass = classLoader.loadClass(myProperties.get(0).getCanonicalName());
LOG.info("Load class name : {}", loadedMyClass.getName());
Constructor constructor = loadedMyClass.getConstructor();
PropertyConfig myClassObject = (PropertyConfig)constructor.newInstance();
LOG.info(myClassObject.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return "done";
}
}
Ожидается, после запуска кода,класс конфигурации будет создан и извлек свойства из файла yml.
Actual, Класс создан, но файл свойств не считан в классе конфигурации.Свойство getName возвращает ноль.
Вывод из журналов:
LOG.info("Property Name : {}", myProperties.toString());
Property Name : [class com.example.demo.properties.dev.A1DevProperty, class com.example.demo.properties.dev.B1DevProperty]
-----
LOG.info("Property type : {}", myProperties.get(0).getCanonicalName());
Property type : com.example.demo.properties.dev.A1DevProperty
-----
LOG.info("Load class name : {}", loadedMyClass.getName());
Load class name : com.example.demo.properties.dev.A1DevProperty
-----
LOG.info(myClassObject.toString());
PropertyConfig{name='null'}
Не уверен, что я делаю неправильно.Есть ли лучший способ сделать это задание или какие-либо предложения?