You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<1> Value is a group id for a dependency identified by name `acme`.
164
164
<2> Value is an artifact id for a dependency identified by name `acme`.
165
165
166
+
[[string-based-qualifiers]]
167
+
== String-Based Qualifiers
168
+
169
+
The `@Named` qualifier, which you might be familiar with, is a _string-based qualifier_.
170
+
That is, it's the string value of the qualifier annotation who determines whether the qualifier matches or not.
171
+
This is not type-safe and should not be the norm in CDI applications.
172
+
Specific qualifier types should be preferred.
173
+
174
+
However, sometimes string-based qualifiers are necessary.
175
+
In that case, avoid the `@Named` qualifier, because in CDI, it works differently to all other qualifiers.
176
+
177
+
Specifically: if the only qualifier a bean has is `@Named`, it also automatically gets `@Default`.
178
+
This means that if multiple beans of the same type exist, one of them without qualifiers and the others with `@Named`, they _all_ get the `@Default` qualifier and bean resolution will error with ambiguity.
179
+
For example:
180
+
181
+
[source,java]
182
+
----
183
+
@ApplicationScoped
184
+
public class Producers {
185
+
@Produces
186
+
MyBean produce() {
187
+
...
188
+
}
189
+
190
+
@Produces
191
+
@Named("foo")
192
+
MyBean produceFoo() {
193
+
...
194
+
}
195
+
}
196
+
197
+
@ApplicationScoped
198
+
public class Consumer {
199
+
@Inject
200
+
MyBean bean;
201
+
}
202
+
----
203
+
204
+
In this case, the `Consumer#bean` injection point will cause ambiguity error, because both `MyBean` producers will have the `@Default` qualifier.
205
+
206
+
Instead of `@Named`, use `@io.smallrye.common.annotation.Identifier`.
207
+
This is a regular qualifier that works like all others.
208
+
So if we rewrite the example to use `@Identifier`:
209
+
210
+
[source,java]
211
+
----
212
+
@ApplicationScoped
213
+
public class Producers {
214
+
@Produces
215
+
MyBean produce() {
216
+
...
217
+
}
218
+
219
+
@Produces
220
+
@Identifier("foo")
221
+
MyBean produceFoo() {
222
+
...
223
+
}
224
+
}
225
+
226
+
@ApplicationScoped
227
+
public class Consumer {
228
+
@Inject
229
+
MyBean bean;
230
+
}
231
+
----
232
+
233
+
Only the first producer will get the `@Default` qualifier, the second will not.
234
+
Hence, there will be no error and everything will work as expected.
235
+
236
+
=== When To Use `@Named`?
237
+
238
+
There is one case where `@Named` is the right thing to use: specifying an external identifier for a different language that doesn't support dependency injection directly.
239
+
240
+
For example:
241
+
242
+
[source,java]
243
+
----
244
+
@ApplicationScoped
245
+
@Named("myBean")
246
+
public class MyBean {
247
+
public String getValue() {
248
+
...
249
+
}
250
+
}
251
+
252
+
@ApplicationScoped
253
+
public class Consumer {
254
+
@Inject
255
+
MyBean bean;
256
+
}
257
+
----
258
+
259
+
As you can see, in the application code, the bean is injected without a qualifier.
260
+
The bean name is only used to refer to the bean in the other language.
261
+
262
+
Historically, the most common external language that used bean names was JSF.
263
+
In Quarkus, we have xref:qute-reference.adoc#injecting-beans-directly-in-templates[Qute].
264
+
In a Qute template, one would refer to the bean using its name:
265
+
266
+
[source]
267
+
----
268
+
The current value is {inject:myBean.value}.
269
+
----
270
+
271
+
Outside of this use-case, just use `@Identifier`.
272
+
166
273
== Native Executables and Private Members
167
274
168
275
Quarkus is using GraalVM to build a native executable.
0 commit comments