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

    В предыдущей статье я рассказал об основных аннотациях 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 легко проглатывает.
    Метки:
    • +4
    • 31,7k
    • 3
    Поделиться публикацией
    Похожие публикации
    Комментарии 3
    • 0
      да, с приходом аннотаций программировать стало гораздо приятнее, много черновой работы убирается. Мне раньше не очень нравился Spring, но когда узнал как работают аннотации в версии 2.5 — любовь на веки.

      Вот примерчик моего рабочего кода
        @RequestMapping(value = "/compset_analysis", params = {"action=hotel-etalons"})
      public ModelAndView getApprovedMarket(@RequestParam(required = false) String market, @Qualifier HotelEtalonsCompSetAnalysisView etalonsView){
      ...
      }


      * This source code was highlighted with Source Code Highlighter.


      обратите внимание как передается параметр @Qualifier HotelEtalonsCompSetAnalysisView etalonsView

      автору, спасибо.
      идем дальше? сможете осветить тему про Lazy, @Transaction, OpenSessionInViewInterceptor, OpenSessionInViewFilter

      • 0
        А вы можете осветить тему про OpenSessionInViewInterceptor, OpenSessionInViewFilter?
        Думаю, что пока вы напишете — я найду решение свой проблемы, но потом другим людям полезно будет.

        Спасибо.
      • 0
        Я думаю здорово было бы отметить как работает @Autowired для множества бинов.
        Если есть некий интерфейс A и несколько бинов, реализующих этот интерфейс заавтовайрить можно их всех:

        @Autowired
        private Set<A> aSet;
        

        btw, автовайринг одного бина по типу A приведёт к исключению.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.