Вот где я застрял (класс инструменталистов).
- Требуется ли аннотация @Component в этом классе? Или это только
требуется, если на класс нужно ссылаться из другого класса?
Да, если вы хотите, чтобы сканирование аннотаций создавало для вас компонент из класса без отдельной xml-конфигурации. Поскольку вы запрашиваете Instrumentalist
-реализацию с именем bean kenny (по имени, а не по типу Instrumentalist
) в вашем main-методе, его также необходимо назвать.
Классы, аннотированные @Component, @Repository, @Controller и @Service, - это те, которые Spring сканирует при настройке ApplicationContext. Разница между этими четырьмя аннотациями семантическая (дифференцирующая роль класса в коде), они все делают одно и то же (если, например, у вас нет AOP-материала, который обрабатывает только определенные типы аннотаций; сейчас вы не не нужно заботиться об этом).
Аннотирование класса любой из вышеупомянутой аннотации аналогично объявлению bean-компонента в xml:
<bean id="saxophone" class="com.sia.ch1.instrumentalist.Saxophone"> ... </bean>
совпадает с
@Component
public class Saxophone implements Instrument{
Обратите внимание, что по умолчанию bean-компонент назван так же, как и класс, за исключением того, что первая буква имени класса изменяется на нижний регистр (поэтому @Component public class SomeClass
создаст bean-компонент с именем "someClass").
Если вы хотите назвать свой компонент, вы даете имя в качестве параметра для аннотации:
@Component("kenny")
public class Instrumentalist implements Performer {
совпадает с
<bean id="kenny" class="com.sia.ch1.instrumentalist.Instrumentalist">
Другим способом присвоения параметра аннотации будет использование @Component(value="kenny")
. Причина, по которой value = -part является необязательной, заключается в том, что аннотации работают следующим образом: если задан только один параметр без указания имени поля, а аннотация содержит поле с именем value , для параметра будет установлено значение значение . Если имя поля является чем-то другим или вы хотите задать несколько полей аннотации, вам нужно явно определить поля: @SomeAnnotation(field1="some string", field2 = 100)
или @SomeAnnotation(value="someValue", anotherField="something else")
. Это немного помимо сути, но это хорошо знать, так как поначалу это может сбить с толку.
Итак, аннотация @ Component сообщает контексту Spring, что вы хотите создать bean-компонент (или bean-компоненты, см. @ Scope ) из аннотированных классов. Когда нет аннотации @ Scope , бины будут создаваться как синглтоны по умолчанию (вы можете автоматически связывать бин с несколькими классами, но все они видят один и тот же экземпляр). Для получения дополнительной информации о различных областях, я предлагаю прочитать официальную документацию .
- Я знаю, что мне нужно @Autowire свойства инструмента и песни
но как я могу узнать, хочу ли я автоматически передавать по имени или по типу и т. д.
Обычно, если у вас есть только одна реализация типа (интерфейса), удобнее выполнять автоматическое подключение по типу. Автопроводка по типу работает, когда существует только одна реализация, потому что иначе Spring не может решить, какую реализацию копировать и внедрять.
В вашем случае у вас есть два разных класса, реализующих Instrument
-интерфейс: Saxophone
и Piano
. Если вы попытаетесь выполнить автоматическое подключение с помощью поля Instrument
поля Instrumentalist
, вы получите исключение, когда Spring создаст Instrumentalist
-bean:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.sia.ch1.instrumentalist.annotate.Instrument] is defined: expected single matching bean but found 2: [piano, saxophone]
Поскольку существует две реализации Instrument
, Spring не имеет достаточно информации, чтобы определить, какую из них вы хотите внедрить в Instrumentalist
. Это то место, где вступает аннотация @ Qualifier . С помощью @Qualifier вы указываете Spring вводить зависимость с автопроводкой по имени . Внедрение Piano
-принятия Instrument
с использованием @Qualifier в Instrumentalist
выполняется с помощью:
@Component(value="kenny")
public class Instrumentalist implements Performer
{
@Autowired
@Qualifier("piano")
private Instrument instrument;
совпадает с
<bean id="kenny" class="com.sia.ch1.instrumentalist.Instrumentalist">
<property name="instrument" ref="piano"/>
</bean>
Обратите внимание, что нет необходимости (но вы можете, если хотите) использовать @Component("piano")
в Piano
-классе, так как при присвоении имени по умолчанию первая буква класса изменяется на строчные, а затем используется в качестве bean-компонента. -name.
- Как бы я автоматически связал свойство String, если в этом классе нет бина, который
представляет это? то есть свойство инструмента будет относиться к классу фортепиано, но с чем будет автоматически связано свойство песни?
Здесь линия рисуется с аннотациями (AFAIK); вы не можете объявить bean-компонент типа String с аннотациями (поскольку java.lang.String не является интерфейсом, его нельзя расширять, так как он является окончательным и не имеет интерфейса). Однако с xml-конфигурацией это возможно:
<bean id="songName" class="java.lang.String">
<constructor-arg value="Valley of the Queens"/>
</bean>
Вы можете смешивать и сопоставлять XML и аннотации, а также ссылаться на bean-компоненты, объявленные в xml из аннотаций и наоборот, чтобы вставить этот bean-компонент в *1000* s 'song
-field:
@Autowired
@Qualifier("songName")
private String song;
Надеюсь, что это помогло вам понять аннотации Springs в целом и начать, я все равно настоятельно рекомендую вам прочитать официальную документацию, так как есть еще много. Если вы предпочитаете читать книги вместо экрана, я бы предложил, например, Весенние рецепты Appress (но я уверен, что есть и много других хороших книг).