【问题标题】:Spring - differences between @Named and @ComponentSpring - @Named 和 @Component 之间的区别
【发布时间】:2016-03-24 15:08:42
【问题描述】:

我试图了解这两个注释之间的区别以及它们如何影响 Spring 中的注入。考虑以下代码 -

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ExternalPropertiesHolder {}

当我用这个注释标记一个类时 -

@ExternalPropertiesHolder
public class SomeProperties {}

然后使用@Inject 注入此依赖项,它可以完美运行-

@Service
public class SomeService {
    private SomeProperties someProperties;

    @Inject
    public SomeService(SomeProperties someProperties) {
        this.someProperties = someProperties;
    }
}

但是,当我将 @Component 替换为 @Named -

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Named           // --> Here!
public @interface ExternalPropertiesHolder {}

然后注入失败并出现通常的 bean not found 异常 -

原因: org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 找到类型 [com.hogehoge.SomeProperties] 的合格 bean 依赖项:预计至少有 1 个符合自动装配条件的 bean 这种依赖的候选人。依赖注释:{}

我搜索了 Spring 参考文档,所有关于 is this 的区别 -

JSR-330 没有提供可组合的模型,只是一种识别方式 命名组件。

这是什么意思?这是否意味着我不能使用@Named 来编写这样的自定义标记?还是有别的?

P.S.:当然@Component指的是org.springframework.stereotype.Component@Named指的是javax.inject.Named

【问题讨论】:

  • 它们应该是一样的。刚刚尝试了您的案例,并且仅当您在自定义注释中使用 @Named 时它才起作用。对我来说似乎是一个错误。

标签: java spring dependency-injection


【解决方案1】:

所以我直接从 Juergen Hoeller 那里得到了答案。 According to him,这一行-

JSR-330 没有提供可组合的模型,只是一种识别方式 命名组件。

意味着javax.inject.Named 只能在给定的bean 类上直接声明。可组合的注解故事只适用于 Spring 自己的注解,这正是我所怀疑的。

【讨论】:

    【解决方案2】:

    正确,javax.inject.Namedjavax.anotations.ManagedBean 不提供可组合模型。因此,不能用于与org.springframework.stereotype.Component 相同的意图。

    但我可以从文档中看到,我们可以在这个用例中使用 javax.inject.Qualifier,因为它旨在用于定义自定义注释。

    您尝试过javax 中的@Qualifier 吗?

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Qualifier           // --> from javax.inject
    public @interface ExternalPropertiesHolder {}
    

    甚至@Named 也是使用@Qualifier 定义的。

    @Qualifier
    @Documented
    @Retention(RUNTIME)
    public @interface Named {
    
        /** The name. */
        String value() default "";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-23
      • 2019-04-22
      • 2012-08-07
      • 1970-01-01
      • 2015-12-31
      • 1970-01-01
      • 2017-06-05
      • 1970-01-01
      相关资源
      最近更新 更多