- 08-01-2008
Spring Framework – первые шаги (Конспект второй)
Во время этой лекции нам предстоит разобраться с фундаментальным принципом, положенным в основу работы Spring Framework – Inversion of Control (Ioc).
И надо признаться, что это не простая задача, т.к. единства мнения в целесообразности использования этого принципа нет.
В начале нам предстоит понять, кто кого инвертирует и кто кого контроллирует.
Конспект второй : Inversion of Control vs. Dependancy Injection
Во время этой лекции нам предстоит разобраться с фундаментальным принципом, положенным в основу работы Spring Framework – Inversion of Control (Ioc). И надо признаться, что это не простая задача, т.к. единства мнения в целесообразности использования этого принципа нет.
В начале нам предстоит понять, кто кого инвертирует и кто кого контроллирует. Для того, чтобы читатель не потерял нить рассуждения, я приведу пример, реализованный без каких-либо IoC и DI.
Представьте себе, что вы разрабатываете серверную компоненту, которая должна обрабатывать форму регистрации пользователя и отправлять письмо администратору и самому пользователю по завершении таковой:
В этой строке как раз и заключается вся соль – именно она лишает возможности полноценно использовать RegisterFormController совместно со Spring Framework. Почему, спросите вы? Ведь никакой крамолы в данном коде нет!? Совершенно верно – крамолы нет. Но, использовать полноценно этот класс не получится, т.к. если Вам понадобится не SMTP почтовый агент, а IMAP – Вам придется перерабатывать Ваш код.У приведенного выше класса есть метод send(), который и должен выполнять эту функцию. Обратите особое внимание на строку выделенную красным цветом
Vyacheslav Yakovenko
package com.personality.examples.spring.ioc;
publicclass RegisterFormController {
privatestaticfinal String MESSAGE_HELLO_WORLD = "Hello, World!";
publicvoid send() {
MailService mailService = new SmtpMailService();
try {
mailService.sendMessage(MESSAGE_HELLO_WORLD);
} catch (MailServiceSendMessageException e) {
e.printStackTrace();
}// try/catch
}// send()
}
MailService mailService = new SmtpMailService();
„Но ведь можно разработать фабрику, которая будет возвращать необходимый экземпляр почтового агента!“, - скажет мне искушенный в таких вопросах программист и будет по своему прав. Но ведь нам то хочется иметь возможность декларативного конфигурирования системы! И именно тут при попытке декларативно сконфигурировать нашу систему и возникнет проблема. О том, как ее решить, я расскажу чуть позже, а пока... пока мы вернемся к коду и постараемся анатомировать его.
Итак, код выделенный красным цветом, говорит нам о том, что класс RegisterFormController полностью контроллирует (композиция) процесс создания экземпляра почтового клиента. Т.о. все функции по созданию экземпляров классов, будь то с помощью директивы new, или с помощью фабрики MailService.getInstance() уже не имеет для нас значения. Главное, что все эти функции сосредоточены в самом приложении. Это и есть традиционный способ инстанцирования объектов, характерных для многих приложений. Ну что же, с традиционным способом мы разобрались, теперь подошло время для того, чтобы разобраться с IoC.
Я несколько модифицирую
RegisterFormController, превратив его в
RegisterFormControllerReadyForIoC и добавлю класс Framework, который (да простит меня
Род Джонсон 
), проиллюстрирует то, что делает
Spring. Итак:
Обратите внимание на то, что ничего сверхестественного я не сделал, а просто привел класс в соответствие с
JavaBean спецификацией, добавив методы
setMailService() и
getMailService() и убрав инициализацию свойства
mailService из
класса. Т.о.
класс RegisterFormControllerReadyForIoC уже не контроллирует процесс
создания экземпляра почтового клиента. Ключевая фраза здесь - „уже не контроллирует“. А ведь кто-то должен этот процесс контроллировать

.
Переходим к созданию фреймворка:
package com.personality.examples.spring.ioc;
publicclass Framework {
publicstaticvoid main(String[] args) {
MailService mailService = new SmtpMailService();
RegisterFormControllerReadyForIoC controller = new RegisterFormControllerReadyForIoC();
controller.setMailService(mailService);
controller.send();
}
}
Как видите, в этом случае код, отвечающий за создание экземпляров классов и установления связей между ними, вынесен из класса приложения в... правильно - во фреймворк. В этом и заключается, столько раз упомянутая, инверсия. Именно этот подход и получил название - Inversion of Controll (IoC).
Все сказанное выше, я постараюсь изобразить графически:
Обратите внимание на то, что я сознательно ушел от использования UML диаграмм и постарался создать в Вашем сознании образ того, что происходит в системе, использующей один из IoC (DI) фреймворков.
В следующей лекции, уважаемый читатель сможет познакомиться с тем, как же выполняется декларативная конфигурация приложения, а так же - с различными авторитетными точками зрения на IoC (DI).
В даннм случае метод main() эмулирует вызовы, котрые сделает Spring, для того чтобы подготовить среду окружения для нашего приложения. Как видите, фреймворк создает (инстанцирует) экземпляр почтового агента, затем создает (инстанцирует) экземпляр контроллера, следующим шагом внедряет экземпляр класса (Dependancy Injection) агента в контроллер и уж затем выполняет отправку сообщения.
package com.personality.examples.spring.ioc;
publicclass RegisterFormControllerReadyForIoC {
privatestaticfinal String MESSAGE_HELLO_WORLD = "Hello, World!";
private MailService mailService;
publicvoid send() {
try {
mailService.sendMessage(MESSAGE_HELLO_WORLD);
} catch (MailServiceSendMessageException e) {
e.printStackTrace();
}// try/catch
}// send()
public MailService getMailService() {
return mailService;
}
publicvoid setMailService(MailService mailService) {
this.mailService = mailService;
}
}
Комментарии к статье "Spring Framework – первые шаги (Конспект второй)" (8)
|
|
Алекс
19-10-2009 21-14 Спасибо.очень хорошая статья:) |
|
Vyacheslav Yakovenko
20-05-2009 15-14 Fixed ;) |
|
Виталий
17-05-2009 08-57 +1 к карме (собираю по крупицам соответствующую информацию) |
|
Vyacheslav Yakovenko
05-05-2009 21-27 2 yt: Да, есть проблемы - мы писали в нашей http://Twitter.com/Lifein ленте про обновление дизайна. Будем править! |
|
yt
28-04-2009 20-08 Что-то не то со страницей - в примерах кода огромные буквы. |
|
АлександрНеверов
26-03-2008 10-53 по-моему на этой странице не хватает одного кусочка кода, очень важного, а вообще то статья очень хорошая, спасибо! |
|
Admin
15-02-2008 13-32 Спасибо. Исправлено! |
|
RedMac
13-02-2008 17-44 ссылки на переход к предыдущему и следующему конспектам затисались в середину текста |
|
|