2

A tonne of code at my company uses the javax.inject.Named annotation with the default value, which the Javadoc indicates is the empty string "".

For example:

@Named
public class Foo {
   ... 
}

This does not appear to add any value, since the empty string doesn't have any semantic meaning. If I remove the @Named annotations will there be any harmful effects?

The question What is javax.inject.Named annotation supposed to be used for? describes how @Named functions, but doesn't explain any special significance of the empty string, or why it would be necessary or beneficial to omit the actual name.

The question When should you explicitly name a Managed Bean? likewise talks about when you would want to use names to differentiate injectable beans, but doesn't provide any rationale for the use of the empty string as a name.

Can I delete these un-named @Named annotations without breaking anything?

4

2 回答 2

1

@Named(javax.inject.Named) 等价于@Component(org.springframework.stereotype.Component)。

用于注释类时,表示该类将被扫描注册。如果没有给出名称,DI 框架将在注入依赖项时使用类类型。

简而言之,您无法删除这些@Named注释。如果你这样做,一切都会正常编译。但是,在运行时,您会收到运行时错误,例如找不到 bean xyz。

于 2020-06-06T22:48:49.757 回答
0

如果不分析所有构造注入密钥的代码和注入任何这些绑定的所有代码,就不可能知道你是否会破坏任何东西。

在某些 JSR-330 实现(例如 Dagger)中,不可能使用具有@Named在运行时构造的值的注释,但在其他实现(例如 Guice)中,这是可能的并且实际上通常这样做。

例如,我可以想象一个 Guice 模块,例如:

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);
    }
}

Foo这为委托给 a的未注释提供了绑定@Named(x) Foo,其中x由模块的构造函数参数确定——可以在运行时构造,或者从某处的某个默认值派生,等等。

您可以想象构建一个注入器的代码,例如:

Injector injector = Guice.createInjector(
    ...,
    new DynamicFooModule(getSelectedFooConfig()),
    ...);

WheregetSelectedFooConfig()可能""作为默认或后备返回。

在这种情况下,@Named没有任何名称可能是一个合理的备用值。如果您的应用程序正在做类似的事情,那么删除绑定是不安全的,因为未注释的绑定@Named不等同于具有空字符串的绑定。

我仍然认为这不是一个好的设计:为此目的(例如)使用专用的限定符注释会更好,@ConfigBased("foo-config")而不是仅仅使用@Named. 如果您这样做,那么您至少可以确定正在使用哪些字符串(或者,更好的是,避开字符串并改用枚举)。

于 2019-01-15T17:42:08.193 回答