我试图理解这两个注释之间的差异以及它们如何影响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
。
答案 0 :(得分:0)
所以我直接从Juergen Hoeller那里得到了答案。 According to him,这一行 -
JSR-330不提供可组合模型,只是一种识别方式 命名组件。
表示只能在给定的bean类上直接声明javax.inject.Named
。可组合的注释故事只适用于Spring自己的注释,这正是我所怀疑的。
答案 1 :(得分:0)
正确,javax.inject.Named
和 javax.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 {}