#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()
(полное имя типа).