Spec-Zone .ru
спецификации, руководства, описания, API


Пакет javax.inject

Этот пакет определяет средство для того, чтобы получить объекты таким способом как, чтобы максимизировать возможность многократного использования, тестируемость и пригодность для обслуживания по сравнению с традиционными подходами, такими как конструкторы, фабрики, и локаторы службы (например, JNDI). Этот процесс, известный как внедрение зависимости, выгоден для большинства нетривиальных приложений.

См.:
          Описание

Сводка интерфейса
Провайдер <T> Обеспечивает экземпляры T.
 

Аннотация Вводит Сводку
Ввести Идентифицирует вводимых конструкторов, методы, и поля.
Именованный Основанный на операция со строками спецификатор.
Спецификатор Идентифицирует аннотации спецификатора.
Контекст Идентифицирует аннотации контекста.
Singleton Идентифицирует тип, которого инжектор только инстанцирует однажды.
 

Пакет javax.inject Описание

Этот пакет определяет средство для того, чтобы получить объекты таким способом как, чтобы максимизировать возможность многократного использования, тестируемость и пригодность для обслуживания по сравнению с традиционными подходами, такими как конструкторы, фабрики, и локаторы службы (например, JNDI). Этот процесс, известный как внедрение зависимости, выгоден для большинства нетривиальных приложений.

Много типов зависят от других типов. Например, Stopwatch мог бы зависеть от TimeSource. Типы, от которых зависит тип, известны как его зависимости. Процесс обнаружения, что экземпляр зависимости использует во время выполнения, известен как разрешение зависимости. Если никакой такой экземпляр не может быть найден, зависимость, как говорят, неудовлетворена, и приложение повреждается.

В отсутствие внедрения зависимости объект может разрешить свои зависимости несколькими способами. Это может вызвать конструктора, соединяя объект проводами непосредственно к реализации его зависимости и жизненному циклу:

   class Stopwatch {
     final TimeSource timeSource;
     Stopwatch () {
       timeSource = new AtomicClock(...);
     }
     void start() { ... }
     long stop() { ... }
   }

Если больше гибкости необходимо, объект может обратиться к фабрике или локатору службы:

   class Stopwatch {
     final TimeSource timeSource;
     Stopwatch () {
       timeSource = DefaultTimeSource.getInstance();
     }
     void start() { ... }
     long stop() { ... }
   }

В решении между этими традиционными подходами к разрешению зависимости программист должен сделать компромиссы. Конструкторы являются более краткими, но рестриктивными. Фабрики разъединяют клиент и реализацию до некоторой степени, но требуют шаблонного кода. Локаторы службы разъединяются еще далее, но уменьшают безопасность типов времени компиляции. Все три подхода запрещают поблочное тестирование. Например, если программист использует фабрику, каждый тест против кода, который зависит от фабрики, должен будет дразнить фабрику и не забыть очищать после непосредственно или иначе побочные эффекты риска:

   void testStopwatch() {
     TimeSource original = DefaultTimeSource.getInstance();
     DefaultTimeSource.setInstance(new MockTimeSource());
     try {
       // Now, we can actually test Stopwatch.
       Stopwatch sw = new Stopwatch();
       ...
     } finally {
       DefaultTimeSource.setInstance(original);
     }
   }

Практически, поддержка этой возможности дразнить фабрику приводит к даже большему количеству шаблонного кода. Проверяет ту насмешку, и очистите после того, как многократные зависимости быстро выходят из-под контроля. Чтобы усугубить положение, программист должен предсказать точно, сколько гибкости будет необходимо в будущем или иначе ответит за последствия. Если программист первоначально выбирает использовать конструктора, но позже решает, что больше гибкости требуется, программист должен заменить каждый звонок в конструктора. Если программист допускает ошибку на стороне предостережения и фабрик записи передняя сторона, это может привести к большому количеству ненужного шаблонного кода, добавляя шум, сложность, и подверженный ошибкам.

Внедрение зависимости решает все эти проблемы. Вместо программиста, вызывающего конструктора или фабрику, инструмент, названный инжектором зависимости, передает зависимости к объектам:

   class Stopwatch {
     final TimeSource timeSource;
     @Inject Stopwatch(TimeSource TimeSource) {
       this.TimeSource = TimeSource;
     }
     void start() { ... }
     long stop() { ... }
   }

Дальнейшие зависимости от передач инжектора к другим зависимостям, пока это не создает весь граф объектов. Например, предположите, что программист, которого спрашивают инжектор создает экземпляр StopwatchWidget:

   /** GUI for a Stopwatch */
   class StopwatchWidget {
     @Inject StopwatchWidget(Stopwatch sw) { ... }
     ...
   }

Инжектор мог бы:

  1. Найдите TimeSource
  2. Создайте Stopwatch с TimeSource
  3. Создайте StopwatchWidget с Stopwatch

Это листы код программиста, чистый, гибкий, и относительно свободный от связанной с зависимостью инфраструктуры.

В тестах модуля программист может теперь создать объекты непосредственно (без инжектора) и передать в ложных зависимостях. Программист больше не должен установить и разъединить фабрики или локаторы службы в каждом тесте. Это значительно упрощает наш тест модуля:

   void testStopwatch() {
     Stopwatch sw = new Stopwatch(new MockTimeSource());
     ...
   }

Полное уменьшение в сложности теста модуля пропорционально продукту числа тестов модуля и числа зависимостей.

Этот пакет обеспечивает аннотации внедрения зависимости, которые включают переносимым классам, но ему листы внешняя конфигурация зависимости до реализации инжектора. Программисты аннотируют конструкторов, методы, и поля, чтобы рекламировать их injectability (инжекция конструктора демонстрируется в примерах выше). Инжектор зависимости идентифицирует зависимости class, осматривая эти аннотации, и вводит зависимости во время выполнения. Кроме того инжектор может проверить, что все зависимости были удовлетворены в, создают время. Локатор службы, в отличие от этого, не может обнаружить неудовлетворенные зависимости до времени выполнения.

Реализации инжектора могут принять много форм. Инжектор мог сконфигурировать себя, используя XML, аннотации, DSL (проблемно-ориентированный язык), или даже простой код Java. Инжектор мог положиться на отражательную или генерацию кода. У инжектора, который использует генерацию кода времени компиляции, возможно, даже нет своего собственного представления времени выполнения. Другие инжекторы, возможно, не в состоянии не генерировать код вообще, ни в компиляции, ни время выполнения. "Контейнер", для некоторого определения, может быть инжектором, но эта спецификация пакета стремится минимизировать ограничения на реализации инжектора.

См. Также:
@Inject


Представьте ошибку или функцию

Авторское право © 2009-2011, Oracle Corporation и/или его филиалы. Все права защищены. Использование подвергается срокам действия лицензии.

Сгенерированный на 10-February-2011 12:41

free hit counter