Spring 2.5: використання аннотацій

Про те, що вийшов Spring Framework (www.springframework.org) версії 2.5, я знав вже давно (відносно давно звичайно). Читав про нові можливості даної версії, пробував навіть щось трохи. Але то все було просто так, для себе. Недавно появилася можливість побавитися із Spring 2.5 більш глибше. І я з радістю нею скористався.
Основним моментом, який був для мене цікавим - це використання анотацій у доповнення до XML конфігурації. Саме про це я вирішив трохи написати.

Головним питанням було -- навіщо анотації?
Іншими цікавими питаннями були:
  1. які анотації можна використовувати?
  2. як їх використовувати?
  3. чи можливо працювати і дальше без них?
  4. як можна включати і виключати використання анотацій?
і багато ще інших питань, які виникали по ходу справи.

Отож, про все по порядку.
Анотації не підтримуються по замовчуванню. Для того, щоб їх використовувати, потрібно вказати 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();
}

тоді

@Autowired
@DocumentFinder(documentType="MSWord", finderScope="local")
private DocumentFinder documentFinder;
а в XML

<bean class="DocumentFinder">
<qualifier type="annotation.DocumentFinder">
<attribute name="documentType" value="MSWord"/>
<attribute name="finderScope" value="local"/>
</qualifier>
</bean>

І це ще навіть не всі можливості...
Так, наприклад, я не розказав про @Resource. А також і не згадав досі про можливість використання компонентів, які оголошенні за допомогою анотацій.

Але про це все або читайте в туторіалі від Spring або вже у наступній статті.

No comments: