Spring中无法让@Component被继承?

发布于 2024-11-27 12:04:04 字数 628 浏览 0 评论 0原文

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

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

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

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

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

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.

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

@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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黎歌 2024-12-04 12:04:04

问题是 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()

换句话说,当解析一个类有哪些注释时,注释的注释不会被解析 - 它们不适用于该类,仅适用于该注释(如果这是有道理的话)。

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

Your @InheritedComponent annotation 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 @Component on the annotation, not the parent type.

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()

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).

流云如水 2024-12-04 12:04:04

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

@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 使用过滤器自定义扫描

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:

<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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文