Можно ли использовать @Resource в конструкторе?
Мне было интересно, можно ли использовать аннотацию @Resource
для конструктора.
Мой вариант использования заключается в том, что я хочу связать последнее поле с именем bar
.
public class Foo implements FooBar {
private final Bar bar;
@javax.annotation.Resource(name="myname")
public Foo(Bar bar) {
this.bar = bar;
}
}
Я получаю сообщение о том, что @Resource
не разрешено в этом месте. Есть ли другой способ связать последнее поле?
Ответы
Ответ 1
Из источника @Resource
:
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
//...
}
Эта строка:
@Target({TYPE, FIELD, METHOD})
означает, что эта аннотация может быть помещена только в классы, поля и методы. CONSTRUCTOR
отсутствует.
Ответ 2
Используйте @Autowired
или @Inject
. Это ограничение описано в справочной документации Spring: тонкая настройка автонастройки на основе аннотаций с квалификаторами:
@Autowired применяется к полям, конструкторам и методам с несколькими аргументами, что позволяет сузить через аннотации квалификатора на уровне параметра. Напротив, @Resource поддерживается только для полей и bean методов настройки свойств с помощью одного аргумента. Как следствие, придерживайтесь квалификаторов, если ваша цель внедрения - это конструктор или метод с несколькими аргументами.
Ответ 3
Чтобы дополнить Robert Munteanu ответ и для дальнейшего использования, вот как выглядит использование @Autowired
и @Qualifier
в конструкторе:
public class FooImpl implements Foo {
private final Bar bar;
private final Baz baz;
@org.springframework.beans.factory.annotation.Autowired
public Foo(Bar bar, @org.springframework.beans.factory.annotation.Qualifier("thisBazInParticular") Baz baz) {
this.bar = bar;
this.baz = baz;
}
}
В этом примере bar
просто автоустанавливается (т.е. в этом классе есть только один bean, поэтому Spring знает, что использовать), а baz
имеет квалификатор, чтобы сообщить Spring какой именно bean этого класса мы хотим ввести.