Не удается получить @Component для наследования в Spring?
В моем проекте есть общий базовый класс, который распространяется на все классы клиентов. Это поле @Autowired, которое должно быть введено Hibernate. Все они группируются в другом классе, который имеет @Autowired коллекцию базового класса.
Чтобы уменьшить шаблон для клиентского кода, я пытаюсь получить @Component в наследство. Если @Component не делает этого по умолчанию (видимо он использовал, хотя), я создал эту обходную аннотацию
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
@Inherited
public @interface InheritedComponent {
}
... и аннотировал базовый класс с ним. Это не очень, но я надеялся, что это сработает. К сожалению, этого не произошло, что меня действительно смущает, поскольку @Inherited должен заставить его работать
Есть ли другой способ получить @Component в наследство? Или я просто должен сказать, что любой класс, который расширяет базовый класс, нуждается в этом шаблоне?
Ответы
Ответ 1
Проблема заключается в том, что сам тип аннотации Component
должен быть помечен @Inherited
.
Тип аннотации @InheritedComponent
правильно унаследован любыми классами, которые расширяют суперкласс, который помечен @InheritedComponent
- но он не наследует @Component
. Это связано с тем, что у вас есть @Component
для аннотации, а не для родительского типа.
Пример:
public class InheritedAnnotationTest {
@InheritedComponent
public static class BaseComponent {
}
public static class SubClass extends BaseComponent {
}
public static void main(String[] args) {
SubClass s = new SubClass();
for (Annotation a : s.getClass().getAnnotations()) {
System.out.printf("%s has annotation %s\n", s.getClass(), a);
}
}
}
Вывод:
класс brown.annotations.InheritedAnnotationTest $SubClass имеет аннотацию @brown.annotations.InheritedComponent()
Другими словами, при разрешении тех аннотаций, которые имеет класс, аннотации аннотаций не разрешаются - они не применяются к классу, а только аннотация (если это имеет смысл).
Ответ 2
Я справился с этой проблемой, создав собственную аннотацию (наследуя), а затем настроил сканирование классов:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
@Inherited
public @interface BusinessService {
}
Spring Конфигурация выглядит так:
<context:component-scan base-package="io.bar">
<context:include-filter type="annotation"
expression="io.bar.core.annotations.BusinessService" />
</context:component-scan>
from Spring doc 5.10.3 Использование фильтров для настройки сканирования