Что такое Injection Dependency & Spring Framework?

Possible Duplicates:
What is dependency injection?
What exactly is Spring for?

я хочу знать Что такое Spring Framework? Почему и когда его следует использовать в разработке Java Enterprise? Ответом будет "Структура внедрения зависимости". Хорошо, какие преимущества мы имеем при использовании структур внедрения зависимостей? Идея описания классов со значениями сеттера и/или параметрами конструктора кажется мне странной. Зачем это делать? Потому что мы можем изменить свойства без перекомпиляции проекта? Это все, что мы получаем?

Тогда какие объекты мы должны описать в beans.xml? Все объекты или только несколько?

Самые простые ответы приветствуются

Ответ 1

Мы используем Injection Dependency (DI) для реализации свободной связи. Выбор любого особого контейнера DI не так важен.

Каждый раз, когда вы создаете экземпляр класса с помощью ключевого слова new, вы плотно соединяете свой код с этим классом, и вы не сможете заменить эту реализацию specificl другой (по крайней мере, не перекомпилируя код).

Это выглядело бы как-то в С# (но было бы эквивалентно в Java):

public class MyClass
{
    public string GetMessage(int key)
    {
        return new MessageService().GetMessage(key)
    }
}

Это означает, что если позже вы захотите использовать другой MessageService, вы не сможете.

С другой стороны, если вы введете интерфейс в класс и придерживаетесь Принцип подписи Лискова, вы сможете изменить потребителя и услуги независимо.

public class MyClass
{
    private readonly IMessageService messageService;

    public MyClass(IMessageService messageService)
    {
        if(messageService == null)
        {
            throw new ArgumentNullException("messageService");
        }

        this.messageService = messageService;
    }

    public string GetMessage(int key)
    {
        return this.messageService.GetMessage(key)
    }
}

Хотя это выглядит более сложным, теперь нам удалось следовать принципу Открытый/Закрытый принцип.

Ответ 2

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

Пример

Без DI:

class SaleAction{

 private BillingService billingService;

 public SaleAction(){
   billingService = new CreditCardService(); //dependency is hardcoded
 }

 public void pay(long amount){
   //pre payment logic
   billingService.pay(amount);
   //post payment logic
 }

}

В этом примере предположим, что вы хотите unit test логику предварительной оплаты и логику после оплаты SaleAction... вы не можете, потому что SaleAction подключен к CreditCardService и, вероятно, запуск ваших тестов будет генерировать поддельные платежи.

Теперь тот же пример с DI:

 class SaleAction{

     private BillingService billingService;

     public SaleAction(BillingService service){
       billingService = service; //DI
     }

     public void pay(long amount){
       //pre payment logic
       billingService.pay(amount);
       //post payment logic
     }

    }

Теперь SaleAction отделяется от любой реализации, а это значит, что в вашем тесте вы можете сделать SaleAction action = new SaleAction(new DummyBillingService());.

Надеюсь, что это поможет, там также статья о DI, написанная Мартином Фаулером, что вы можете найти здесь

Ответ 4

Spring превратился в огромную структуру, которая может сбить вас с толку, если вы только пытаетесь обернуть голову вокруг инъекции зависимостей. Проект Google Guice крошечный и только делает DI с чистой Java - без XML и никаких дополнительных функций. Там хорошее вступительное видео, объясняющее DI тоже. http://code.google.com/p/google-guice/

Ответ 5

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

Легко ответить, что Spring представляет собой комбинацию технологий:

  • инъекция зависимостей, которая использует принцип Голливуда, чтобы помочь вам поддерживать интерфейс и реализацию отдельно;
  • аспектно-ориентированное программирование, которое изолирует проблемы перекрестных помех в модулях, которые вы можете применять декларативно. "Привет мир" АОП регистрируется, но все это Spring (например, транзакции, динамические прокси-серверы для удаленного доступа, безопасность и т.д.). Думайте о фильтрах сервлетов, и у вас будет идея;
  • для поддержки общих задач, таких как постоянство (JDBC, Hibernate, iBatis, JDO, JPA и т.д.), удаленный доступ (RMI, HTTP, веб-службы), асинхронный обмен сообщениями (POJO с сообщением), проверка и привязка, веб-MVC (Spring или Struts), такие утилиты, как электронная почта, планирование, безопасность и т.д.

Но более глубокий ответ заключается в том, что вы получаете выгоду от опыта Рода Джонсона в качестве консультанта по проектам Java EE. Он дистиллировал то, что сработало для него на его концертах в интерфейсе 21/ Spring, и теперь вы можете получить все это бесплатно.

Команда Spring пишет код, который разработан, протестирован и более строго соответствует стандартам, чем все, что я когда-либо буду писать. (Представьте себе, что Юрген Холлер набросился на Рода Джонсона, потому что его код не соответствовал стандарту до регистрации.) Я могу рассчитывать на их код рамки, когда я его использую, и сосредоточиться на своей бизнес-проблеме. Я не пишу код котловой плиты снова и снова.

Для меня Spring больше касается архитектурного шаблона, который выступает в качестве руководства для создания веб-приложений. Некоторые люди могут сказать, что они переработаны, и для некоторых проблем они верны, но для тех проблем, с которыми я столкнулся на регулярной основе, Spring - это всего лишь билет.

Что касается подзапросов:

Какие преимущества у нас есть при использовании инфраструктур инъекций зависимостей?

Объекты не должны нести ответственность за управление своими зависимостями. Spring контекст приложения - это просто большой шаблон Factory из GoF. Он поощряет вас к разработке интерфейса, поэтому вы можете изменить реализацию по мере необходимости. Ваш интерфейс persistence может использовать JDBC-реализацию сегодня, Hibernate завтра; вы можете решить автоматически генерировать прокси-сервер для управления своим транзакционным поведением. Ни один из кодов клиента не должен меняться, если вы кодируете интерфейс.

Идея описания классов со значениями setter и/или параметрами конструктора кажется мне странной. Зачем это? Поскольку мы можем изменить свойства без перекомпиляции  проект? Это все, что мы получаем?

Странно? Вы не используете в своем коде свойства или конструкторы? Вы делаете это, потому что так написано большинство классов Java. Spring просто использует эти механизмы как способ обеспечения зависимостей класса.

Затем, какие объекты мы должны описывать в beans.xml? Все объекты или только несколько?

Только beans, которые имеют зависимости. Я все еще называю "новым" для объектов, которые являются локальными для определенного метода. Они создаются, используются и мусор собираются в рамках метода. Они не должны находиться под управлением Spring.

Ответ 6

У вас уже есть хорошие ответы здесь, я хочу задать пару конкретных вопросов, которые у вас есть:

Идея описания классов со значениями setter и/или параметрами конструктора кажется мне странной. Зачем это? Потому что мы можем изменить свойства без перекомпиляции проекта? Это все, что мы получаем?

Сначала это кажется странным, но дело в том, что контейнер отвечает за включение зависимостей для объектов, сами объекты не отвечают за это. Объем объектов, сконфигурированных в beans.xml, управляется Spring, поэтому нам не нужно так беспокоиться о вещах, которые создаются без правильных зависимостей (если конфигурация верна, я был известен написать модульные тесты, чтобы проверить, что конфигурация spring делает то, что я хочу.)

Затем, какие объекты мы должны описывать в beans.xml? Все объекты или только несколько?

Типы объектов, описанные в beans.xml, являются в основном компонентами - контроллерами, службами, объектами доступа к данным и вещами, которые им нужны, например, менеджерами транзакций, спящими сессионными фабриками, источниками данных и т.д. Объекты домена обычно извлекаются из объектов доступа к данным или создаются непосредственно, потому что они не имеют зависимостей ни от каких объектов, кроме других объектов домена (или от классов полезности, которые еще более независимы, чем классы домена).

Ответ 7

Мнение: Подумайте, какую проблему вы пытаетесь решить с помощью DI и возьмите фреймворк, который подходит лучше всего. Spring может значительно осложнить вашу проблему.

(Одна из первые статьи о DI Мартином Фаулером. Я думаю, что термин DI был придуман в этой статье.)

Ответ 8

Здесь хорошее видео, данное Боб Ли, и два из его исследований по поводу Guice (Guice - это система инъекций зависимостей, например Spring). Первые 10 или около того минут о том, почему Guice (или инъекция зависимостей) будет лучше, чем альтернатива (Фабрики), так что это не все, что касается Guice.

Ответ 9

Возможно, вам не следует пытаться предпринимать "развитие предприятия Java", не имея представления об основных проблемах архитектуры и дизайна? Я предлагаю вам либо найти опытного сотрудника, который готов помочь вам, либо приложить больше усилий для чтения этих книг, либо иначе следовать за курсом.

В любом случае нет "простого ответа" на ваш вопрос.

Ответ 10

Включение зависимостей для отсутствующих виртуальных классов!

 

NB: если вы не знаете, что такое виртуальные классы, обратитесь к "Виртуальные классы, кто-нибудь?" .