Основним моментом, який був для мене цікавим - це використання анотацій у доповнення до XML конфігурації. Саме про це я вирішив трохи написати.
Головним питанням було -- навіщо анотації?
Іншими цікавими питаннями були:
- які анотації можна використовувати?
- як їх використовувати?
- чи можливо працювати і дальше без них?
- як можна включати і виключати використання анотацій?
Отож, про все по порядку.
Анотації не підтримуються по замовчуванню. Для того, щоб їх використовувати, потрібно вказати Spring, що ви хочете працювати і з ними тоже. Для цьому слід добавити у ваш spring.xml наступний рядок:
<context:annotation-config/>.
Namespace context підключається так
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=" http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
Після цього, в нас появляється можливість використовувати анотації.
А тепер детальніше про самі анотанції. Так ми вже можемо використовувати їх, але які вони є, навіщо вони використовуються?
Найбільш поширеною видається анотації
@Autowired
. Дана анотація, вказує що в контейнер Spring повинен виконати автоматичне встановлення значення. Дану анотацію можна використовувати для автоматичного встановлення значення в конструкторі, для поля класу, для сеттера. Наприклад:В даному випадку автозаповнення за допомогою анотації
public class DocumentManager {
@Autowired
private DocumentFinder documentFinder;
private DocumentDao documentDao;
private Document documentPrototype;
@Autowired
public DocumentManager(DocumentDao documentDao) {
this.documentDao = documentDao;
}
@Autowired
public void setPrototype(Document document) {
documentPrototype = prototype;
}
}
@Autowired
, Spring буде виконувати на основі типів полів чи аргументів. Але виникає проблема, коли, наприклад, у вас може бути більше одного біна із типом DocumentFinder
або Document
. Що робити тоді, як Spring має знати яке саме значення слід вставити в певне поле? І саме тут вступає у гру анотація @Qualifier
.Анотація
@Qualifier
дозволяє вказати, який саме container-managed bean
використовувати як значення для заповнення. Дану анотацію можна використовувати як для полів класу, так і для параметрів конструктора або інших методів, так само і для сеттерів. Назва біна, який повинен бути вставленим як значення поля чи параметра вказується як value анотації @Qualifier
. Доволі просто і зручно, самі подивіться на код:
public class DocumentManager {
@Autowired
@Qualifier("defaultDocumentFinder")
private DocumentFinder documentFinder;
private DocumentDao documentDao;
private Document documentPrototype;
@Autowired
public DocumentManager(@Qualifier("hibernateDocumentDao")DocumentDao documentDao) {
this.documentDao = documentDao;
}
@Autowired
public void setPrototype(@Qualifier("prototypeDocument")Document document) {
documentPrototype = prototype;
}
}
Доречі, Spring дозволяє за допомогою XML вказати явно, який
qualifier
у певного bean. Для цього використовується піделемент <qualifier>
елемента <bean>
. Він має такі атрибути, як:- type - тип анотації, що використовується (про це пізніше)
- value - це значення унікальне для даного біна.
Наприклад, якщо в коді вказано:
@Autowired
@Qualifier("prototypeDocument")
public void setPrototype(Document document) {
documentPrototype = prototype;
}
, то в XML
<bean class="Document">
<qualifier value="prototypeDocument"/>
</bean>
<bean class="Document">
<qualifier value="privateDocument"/>
</bean>
І як ви вже певно зрозуміли, при автозаповнення буде використаний перший bean, тому що його
qualifier value
є prototypeDocument
.Але це ще не всі можливості, які надає Spring у питанні вирішення, який саме bean повинен бути використаний для автозаповнення. Так, наприклад, ви можете створювати власні анотації, які використовувати замість
@Qualifier
.Наприклад:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface DocumentFinder {
String documentType();
String finderScope();
}
тоді
а в XML
@Autowired
@DocumentFinder(documentType="MSWord", finderScope="local")
private DocumentFinder documentFinder;
<bean class="DocumentFinder">
<qualifier type="annotation.DocumentFinder">
<attribute name="documentType" value="MSWord"/>
<attribute name="finderScope" value="local"/>
</qualifier>
</bean>
І це ще навіть не всі можливості...
Так, наприклад, я не розказав про
@Resource
. А також і не згадав досі про можливість використання компонентів, які оголошенні за допомогою анотацій.Але про це все або читайте в туторіалі від Spring або вже у наступній статті.