Pull to refresh

Spring IoC Annotation-based configuration, часть 2

Reading time 4 min
Views 44K
В предыдущей статье я рассказал об основных аннотациях Spring IoC, однако есть еще несколько интересных вещей, о которых хотелось бы поведать.
Для, тех, кто не в курсе, что такое Spring Framework предлагаю почитать вот эту статью.



Еще несколько слов об @Autowired


Аннотация @Autowired может применяться не только к полям бина чтобы заинъектить в них зависимости, но так же к сеттерам, конструкторам и методам. Рассмотрим, что же будет значить @Autowired в каждом из этих случаев.

1. @Autowired примененный к сеттеру
Пусть наш подопытный бин, который мы будет инъектить выглядит так:
package ru.mypackage;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service("testBean")
@Scope("singleton")
public class TestBean {
  private String data = "I am a singleton!!";
  
  public String getData() {
    return data;
  }

  public void setData(String data) {
    this.data = data;
  }
}


* This source code was highlighted with Source Code Highlighter.

А бин, в который будем инъектить такой:
package ru.mypackage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service("lab1Bean")
@Scope("session")
public class SimpleBean {

  private TestBean bean;

  @PostConstruct
  public void init() {
    System.out.println(bean.getData());
  }

  public void setBean(TestBean bean) {
    this.bean = bean;
  }
}


* This source code was highlighted with Source Code Highlighter.

Собственно в таком случае, если мы поставим @Autowired перед сеттером setBean:
@Autowired
public void setBean(TestBean bean) {
  this.bean = bean;
}


* This source code was highlighted with Source Code Highlighter.

он заинъектит в поле бина синглтон TestBean'a и в консоли мы увидим заветное «I am a singleton!!».

2. @Autowired примененный к конструктору
Ситуация аналогичная — если мы добавим вот такой конструктор:
@Autowired
public SimpleBean (TestBean bean) {
  this.bean = bean;
}


* This source code was highlighted with Source Code Highlighter.

то в консоли увидим долгожданное «I am a singleton!!».

3. @Autowired примененный к методу
Самая интересная ситуация, добавляем вот такой метод
@Autowired
public void doSomething(TestBean bean) {
  this.bean = bean;
  System.out.println("I'm an autowired method and " + bean.getData());
}


* This source code was highlighted with Source Code Highlighter.

Spring автоматически вызовет doSomething и передаст ему экземпляр TestBean. В консоли появится:
I'm an autowired method and I am a singleton!!!
I am a singleton!!!
Первое напечатает doSomething, второе — init.
Обратите внимание, что необходимо устанавливать значение поля бина, Spring за вас этого не сделает. То есть если не писать this.bean = bean;, то в методе init будет NullPointerException.
Еще у @Autowired есть необязательное свойство required. При required=false Spring не будет кидать исключение, если не найдет в контексте необходимого бина. То есть вот такой класс вполне нормально создастся:
package ru.mypackage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service("lab1Bean")
@Scope("session")
public class SimpleBean {

  @Autowired(required=false)
  private TestBean bean;

  @PostConstruct
  public void init() {
//    System.out.println(bean.getData());
  }

  public void setBean(TestBean bean) {
    this.bean = bean;
  }
}


* This source code was highlighted with Source Code Highlighter.

Аннотация Qualifier


Данная аннотация позволяет несколько специфицировать бин, который необходим для @Autowired. Qualifier принимает один входной параметр — имя бина.
@Autowired
@Qualifier("specialTestBean")
private TestBean bean;


* This source code was highlighted with Source Code Highlighter.

Эта конструкция будет искать в контексте бин с именем specialTestBean и в нашем примере мы соответственно получим исключение, так как TestBean объявлен с именем 'testBean' (@Service(«testBean»)).
На основе Qualifier можно создавать свои признаки бинов, об этом достаточно хорошо написано (и, что немаловажно, с огромным количеством примеров) в Spring Reference Manual.

Аннотация Resource


Resource — аннотация Java EE 5 и Java 6. По действию аналогична @Autowired. В качестве параметра 'name' может принимать имя бина. Примеры выше можно переписать вот так:
// @Autowired
// аналогично
@Resource
private TestBean bean;


* This source code was highlighted with Source Code Highlighter.

и
// @Autowired
// @Qualifier("specialTestBean")
@Resource(name="specialTestBean")
private TestBean bean;


* This source code was highlighted with Source Code Highlighter.


На этом про аннотации Spring IoC можно закончить. Надо подвести какие-то выводы...
Spring безусловно стал стройнее, красивее с приходом стиля конфигурирования аннотациями, однако, как показывает практика, механизм пока не отлажен, т.к. иногда случается, что Spring хоть убей не хочет принимать аннотированный бин, а описанный через XML легко проглатывает.
Tags:
Hubs:
+4
Comments 3
Comments Comments 3

Articles