Как найти все классы конфигурации в пакете и сохранить экземпляр каждого из них весной - PullRequest
0 голосов
/ 06 апреля 2019

Я пытаюсь выяснить, как загрузить все классы конфигурации в пакет и сохранить его на карте.Эта карта будет передана в другие сервисы для получения их конфигураций.Каждый пакет представляет собой отдельную среду, и каждый класс конфигурации извлекается из отдельного файла 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'}

Не уверен, что я делаю неправильно.Есть ли лучший способ сделать это задание или какие-либо предложения?

...