java 无法在Spring中继承@Component?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6912330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 17:52:49  来源:igfitidea点击:

Can't get @Component to be inherited in Spring?

javaspringannotations

提问by TheLQ

In my project there's a common base class that all client classes extend. This has an @Autowired field that needs to be injected by Hibernate. These are all grouped together in another class that has an @Autowired collection of the base class.

在我的项目中,有一个所有客户端类都扩展的公共基类。这有一个@Autowired 字段,需要由 Hibernate 注入。这些都在另一个类中组合在一起,该类具有基类的 @Autowired 集合。

In order to reduce boilerplate for client code I'm trying to get @Component inherited. With @Component not doing this by default (apparently it used to though), I created this workaround annotation

为了减少客户端代码的样板,我试图继承@Component。默认情况下@Component 不这样做(显然它曾经这样做过),我创建了这个解决方法注释

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

... and annotated the base class with it. Its not pretty but I hoped it would work. Unfortunately it didn't, which really confuses me as @Inherited should make it work

...并用它注释基类。它不漂亮,但我希望它会起作用。不幸的是它没有,这真的让我感到困惑,因为@Inherited 应该让它工作

Is there any other way to get @Component inherited? Or do I just have to say that any class that extends the base class needs this boilerplate?

有没有其他方法可以继承@Component?或者我必须说任何扩展基类的类都需要这个样板?

采纳答案by matt b

The problem is that the Componentannotation type itself needs to be marked with @Inherited.

问题是Component注解类型本身需要用@Inherited.

Your @InheritedComponentannotation type is correctly inherited by any classes that extend a superclass which is marked with @InheritedComponent- but it does not inherit @Component. This is because you have @Componenton the annotation, not the parent type.

您的@InheritedComponent注释类型被任何扩展超类的类正确继承,该超类标记为@InheritedComponent- 但它不继承@Component。这是因为您@Componentannotation 上,而不是在父类型上。

An example:

一个例子:

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);
        }
    }
}

Output:

输出:

class brown.annotations.InheritedAnnotationTest$SubClass has annotation @brown.annotations.InheritedComponent()

类 brown.annotations.InheritedAnnotationTest$SubClass 有注解 @brown.annotations.InheritedComponent()

In other words, when resolving what annotations a class has, the annotations of the annotations are not resolved - they do not apply to the class, only the annotation (if that makes sense).

换句话说,当解析一个类有什么注解时,注解的注解并没有得到解析——它们不适用于类,只应用于注解(如果有意义的话)。

回答by noleto

I've dealt with this issue by creating my own annotation (heritable) and then customizing classpath scanning:

我通过创建自己的注释(可继承)然后自定义类路径扫描来处理这个问题:

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

Spring configuration look likes this:

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 Using filters to customize scanning

来自Spring doc 5.10.3 使用过滤器自定义扫描