Загрузка компонентов / классов в список массивов с помощью некоторого шаблона имен компонентов

#java #spring #singleton #components #classloader

#java #spring #синглтон #Компоненты #загрузчик классов

Вопрос:

У меня есть несколько классов одного и того же типа ( com.project.abc.abs.Agent ), аннотированных следующим образом;

@Component("WEB.Agent-1"), @Component("WEB.Agent-2"), @Component("WEB.Agent-3") … и т.д. Пока предположим, что все классы находятся в одном пакете ( com.project.abc.web.Agent1... ) .

Все эти классы являются одиночными, и я хочу динамически загружать их в центральный класс «Менеджер агентов». Т.Е. Каждый раз, когда добавляется новый класс агента с @Component("WEB.Agent-#") аннотацией, он выбирается без необходимости вносить изменения в менеджер агентов. В классе AgentManager мне нужен какой-то метод для загрузки любого компонента, который соответствует имени «WEB.Agent-#» (где # — число или некоторый уникальный идентификатор) возможно ли это с использованием каких-либо методов в Spring?

Если нет, я предполагаю, что мне нужно будет загружать все классы из определенной папки / пакета?

Ответ №1:

Вы можете сделать это с ClassPathScanningCandidateComponentProvider помощью и добавить фильтр исключения, который удаляет вещи, которые не соответствуют вашему шаблону:

 ClassPathScanningCandidateComponentProvider scanner =
    new ClassPathScanningCandidateComponentProvider();

scanner.addIncludeFilter(new AnnotationTypeFilter(Component.class));
scanner.addExcludeFilter(new TypeFilter(){
    public boolean match(MetadataReader metadataReader, 
                         MetadataReaderFactory metadataReaderFactory){
        return metadataReader.getAnnotationMetadata()
                 .getAnnotationAttributes(Component.class.getName())
                 .get("value").matches("WEB.Agent-[0-9] ");
    }
});

for (BeanDefinition bd : scanner.findCandidateComponents("com.project.abc.web.Agent1"))
    System.out.println(bd.getBeanClassName());
  

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

1. Спасибо, Марк, похоже, для этого .getAnnotationAttributes() требуется строковый аргумент, должен ли это быть a .getAnnotationAttributes("Component") ?

2. При выполнении цикла for я получаю сообщение об ошибке org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: file

3. @NightWolf, я думаю, вам нужно указать Component.class.getName() (полное имя типа).