Java 删除没有名称的@Named注释安全吗?
我公司的一吨代码使用带有默认值的Java 删除没有名称的@Named注释安全吗?,java,dependency-injection,jsr330,Java,Dependency Injection,Jsr330,我公司的一吨代码使用带有默认值的javax.inject.Named注释,这表明是空字符串“” 例如: @Named public class Foo { ... } 这似乎没有添加任何值,因为空字符串没有任何语义含义。如果我删除@命名的注释,会有任何有害影响吗 这个问题描述了@Named如何工作,但没有解释空字符串的任何特殊意义,也没有解释为什么省略实际名称是必要的或有益的 这个问题同样讨论了何时需要使用名称来区分可注入bean,但没有提供使用空字符串作为名称的任何理由 我可以删除这
javax.inject.Named
注释,这表明是空字符串“”
例如:
@Named
public class Foo {
...
}
这似乎没有添加任何值,因为空字符串没有任何语义含义。如果我删除@命名的
注释,会有任何有害影响吗
这个问题描述了@Named
如何工作,但没有解释空字符串的任何特殊意义,也没有解释为什么省略实际名称是必要的或有益的
这个问题同样讨论了何时需要使用名称来区分可注入bean,但没有提供使用空字符串作为名称的任何理由
我可以删除这些未命名的
@命名的注释而不破坏任何内容吗?如果不分析构造注入键的所有代码和注入这些绑定的所有代码,就不可能知道是否会破坏任何内容
在一些JSR-330实现(例如Dagger)中,不可能使用在运行时构造值的@命名的
注释,但在其他实现(例如Guice)中,这是可能的,事实上通常是这样做的
例如,我可以想象这样一个GUI模块:
public final class DynamicFooModule extends AbstractModule {
private final String whichFoo;
public DynamicFooModule(String whichFoo) {
this.whichFoo = whichFoo;
}
@Override
protected void configure() {
Key<Foo> fooKey = Key.get(Foo.class, Names.named(whichFoo));
Provider<Foo> fooProvider = getProvider(fooKey);
bind(Foo.class).toProvider(fooProvider);
}
}
其中,getSelectedFooConfig()
可能会返回”
,作为默认值或回退
在这种情况下,没有任何名称的@Named
可能是一个合理的回退值。如果您的应用程序正在执行类似的操作,那么删除@命名的
绑定是不安全的,因为未注释的绑定并不等同于带有空字符串的绑定
我仍然认为这不是一个好的设计:最好为此使用一个专用的限定符注释(例如@ConfigBased(“foo-config”)
),而不仅仅是使用@Named
。如果您这样做,那么您至少可以确定正在使用哪些字符串(或者更好的是,避免使用字符串,而是使用枚举)。
(javax.inject.Named)相当于@Component
(org.springframework.stereotype.Component)
当用于注释类时,它表示将扫描并注册该类。如果没有给出名称,DI框架将在注入依赖项时使用类类型
简而言之,您不能删除那些名为@的注释。如果您这样做,一切都将正常编译。然而,在运行时,您将得到运行时错误,比如找不到bean xyz 我认为这里隐含的答案是:这不是@Named
的目的,您描述的代码是对@Named
的滥用。我想更进一步地说,@命名
本身几乎100%都是一个错误。如果您想要一个由字符串参数化的注释,您可以创建自己的注释,但是如果您到处使用@Named
,您已经用“stringly-typed”系统替换了基于注释类型的类型系统,值得注意的是,Guice@com.google.inject.name.Named
注释(AFAIK是JSR-330的@javax.inject.Named
的灵感来源)没有字符串的默认值,因此没有参数的@Named
将是一个编译错误。我不知道为什么JSR-330小组决定添加一个默认值。@DanielPryden,即使在你的评论中,你实际上也没有回答这个问题。说“这不是@所说的
”和“这是一种误用”实际上并不能回答问题,这有什么影响吗?次要问题是删除它安全吗?@DanielPryden,以什么方式问“X有任何影响吗?”以及次要问题“删除X安全吗?”模棱两可?你能指出歧义,这样我就可以编辑我的问题来消除它吗?这同样适用于CDIBean、EJB、JPA实体类等。。这是非常明确的。如果我理解你的意思,至少在Guice的情况下,我必须提供一个明确的funky绑定,以便@Named
产生任何效果?
Injector injector = Guice.createInjector(
...,
new DynamicFooModule(getSelectedFooConfig()),
...);