It's impossible to know if you will break anything without analyzing all the code that constructs injection keys and all the code that injects any of these bindings.
In some JSR-330 implementations (e.g. Dagger) it's not possible to use a @Named
annotation with a value constructed at runtime, but in other implementations (e.g. Guice) it is possible and in fact commonly done.
For example, I could imagine a Guice module like:
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);
}
}
This provides a binding for an unannotated Foo
which delegates to a @Named(x) Foo
, where x
is determined by a constructor argument to the module -- which could be constructed at runtime, or derived from some default somewhere, etc.
You could imagine code building an injector like:
Injector injector = Guice.createInjector(
...,
new DynamicFooModule(getSelectedFooConfig()),
...);
Where getSelectedFooConfig()
might return ""
as a default or fallback.
In a situation like that, @Named
without any name could be a reasonable fallback value to use. If your application is doing anything like that, then it is not safe to remove the @Named
bindings, because an un-annotated binding is not equivalent to a binding with an empty string.
I still would argue that this is not a good design: it would be better to use a dedicated qualifier annotation for this purpose (e.g. @ConfigBased("foo-config")
) rather than just using @Named
. If you were doing that then you could at least identify which strings were being used (or, better yet, eschew strings and use an enum instead).