Spring - @Named和@Component之间的差异

时间:2016-03-24 15:08:42

标签: java spring dependency-injection

我试图理解这两个注释之间的差异以及它们如何影响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 -

  

引起:   org.springframework.beans.factory.NoSuchBeanDefinitionException:没有   找到[com.hogehoge.SomeProperties]类型的限定bean   依赖:预计至少有1个bean有资格成为autowire   这种依赖的候选人。依赖注释:{}

我搜索了Spring参考文档,所有它都要说明差异is this -

  

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

这是什么意思?这是否意味着我无法使用@Named撰写这样的自定义标记?或者还有其他什么?

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

2 个答案:

答案 0 :(得分:0)

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

  

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

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

答案 1 :(得分:0)

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

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

你试过@Qualifier的{​​{1}}了吗?

javax

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

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