Не удается получить @Component для наследования в Spring? - PullRequest
12 голосов
/ 02 августа 2011

В моем проекте есть общий базовый класс, который расширяет все клиентские классы.Это поле @Autowired, которое должно быть введено Hibernate.Все они сгруппированы в другом классе, который имеет коллекцию @Autowired базового класса.

Чтобы уменьшить шаблон кода клиента, я пытаюсь получить @Component унаследованным.Поскольку @Component не делает этого по умолчанию (по-видимому, , хотя раньше ), я создал эту временную аннотацию

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
@Inherited
public @interface InheritedComponent {
}

... и аннотировал базовый класс.Это не красиво, но я надеялся, что это сработает.К сожалению, это не так, что меня действительно смущает, так как @Inherited должен заставить его работать

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

Ответы [ 2 ]

9 голосов
/ 02 августа 2011

Проблема в том, что сам тип аннотации 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 ()

Другими словами, при разрешении того, какие аннотации имеет класс, аннотации аннотаций не разрешаются -они не относятся к классу, только аннотация (если это имеет смысл).

7 голосов
/ 02 октября 2013

Я решил эту проблему, создав собственную аннотацию (наследуемую), а затем настроив сканирование пути к классам:

@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>

из Spring doc 5.10.3 Использование фильтров для настройки сканирования

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...