18124

Spring Framework

Лекция

Информатика, кибернетика и программирование

Тема 9: Spring Framework Spring є Java framework який надає розробнику сукупність сервісів для побудови масштабованих J2EE програм. Spring реалізує в собі концепцію MVC. Inversion of Control IoC Іноді можна почути терміни Inversion of Control та Dependency Injection як взаємозамінні але це не зовсім вірно. Inversion of Co...

Украинкский

2013-07-06

86 KB

1 чел.


Тема 9: Spring Framework

Spring є Java framework, який надає розробнику сукупність сервісів для побудови масштабованих J2EE програм. Spring реалізує в собі концепцію MVC.

Inversion of Control (IoC)

Іноді можна почути терміни Inversion of Control та Dependency Injection як взаємозамінні, але це не зовсім вірно. Inversion of Control набагато більш загальна річ, що виражається багатьма різними способами. Dependency Injection є одним з таких способів.

Inversion of Control покриває широке поле методів, які дозволяють об’єкту бути пасивним учасником в системі. Коли застосовується IoC метод, то об’єкт передає контроль над якимись своїми властивостями чи аспектами framework'у чи середовищу. Прикладами такого контролю можуть бути створення об’єктів чи передача управління залежним об’єктам. IoC може виключити необхідність явного програмування вказаних дій за допомогою використання Dependency Injection та аспектно-орієнтованого програмування (Aspect-Oriented Programming AOP) відповідно.

 Приклад AOP.

Припустимо, є бізнес-компонент, який вимагає забезпечення безпеки у вигляді авторизації при своєму використанні.

public class BankAccount {

public void transfer(BigDecimal amount, BankAccount recipient) {

SecurityManager.hasPermission(this, Permission.TRANSFER,

SecurityContext.getCurrentUser());

recipient.deposit(this.withdraw(amount));

}

public void closeOut() {

SecurityManager.hasPermission(this, Permission.CLOSE_OUT,

SecurityContext.getCurrentUser());

this.open = false;

}

public void changeRates(BigDecimal newRate) {

SecurityManager.hasPermission(this, Permission.CHANGE_RATES,

SecurityContext.getCurrentUser());

this.rate = newRate;

}

}

Недоліком даного коду є постійність перевірки безпеки, яка до того ж спричиняє перемішування коду перевірки безпеки і бізнес-логіки. Бажано, щоб код мав наступний вигляд і при цьому безпека зберігалась:

public class BankAccount {

public void transfer(BigDecimal amount, BankAccount recipient) {

recipient.deposit(this.withdraw(amount));

}

public void closeOut() {

this.open = false;

}

public void changeRates(BigDecimal newRate) {

this.rate = newRate;

}

}

Це може забезпечити AOP шляхом застосування так званих аспектів (aspects). Аспекти – це правила програми, які застосовуються автоматично в масштабах певної частини програмної системи. Відповідно налаштований за допомогою xml-файлів AOP framework (як частина Spring), буде автоматично вставляти відповідний код (в даному випадку перевірки авторизації) у всі потрібні методи.

Dependency Injection

Поняття Dependency Injection є стержневим в Spring. Dependency Injection є методом об’єднання різних об’єктів в єдину систему. При його застосування framework сам забезпечує встановлення зв’язків між об’єктами, позбавляючи програміста необхідності написання в своєму коді логіки зв’язування об’єктів чи створення об’єктів.

Якщо два об’єкти зв’язані, бажано, щоб зв’язок не був жорстким і не був прив’язаний до конкретного середовища.

Приклад.

public interface CashRegister {

public BigDecimal calculateTotalPrice(ShoppingCart cart);

}

public interface PriceMatrix {

public BigDecimal lookupPrice(Item item);

}

public class CashRegisterImpl implements CashRegister {

private PriceMatrix priceMatrix = new PriceMatrixImpl();

public BigDecimal calculateTotalPrice(ShoppingCart cart) {

BigDecimal total = new BigDecimal("0.0");

for (Item item : cart.getItems()) {

total.add(priceMatrix.lookupPrice(item));

}

return total;

}

}

В даній програмі є ряд недоліків.  По-перше, для кожного екземпляру CashRegisterImpl потрібен окремий екземпляр PriceMatrixImpl. Якщо створення і зберігання PriceMatrixImpl є витратними операціями, то це має значення. Для, наприклад, віддалених (remote) ресурсів або таких, що вимагають використання зовнішніх ресурсів, наприклад, баз даних, бажано мати один створений об’єкт, який паралельно використовуватиметься багатьма іншими об’єктами. По-друге, що ще більш важливо, CashRegisterImpl жорстко прив’язаний до конкретної реалізації PriceMatrix – PriceMatrixImpl. Третя проблема є прямим наслідком жорсткої зв’язаності – явно створюючи PriceMatrixImpl всередині CashRegisterImpl, програміст створює ситуацію, складну для тестування, тому що не дає можливості вставити mock-об’єкт замість реального PriceMatrixImpl для тестування.

Використання Dependency Injection перекладає відповідальність за створення та знаходження внутрішнього об’єкту зі створюваного класу на framework. Є дві техніки застосування Dependency Injection. Перша – constructor-based injection. Приклад:

public class CashRegisterImpl implements CashRegister {

private PriceMatrix priceMatrix;

public CashRegisterImpl(PriceMatrix priceMatrix) {

this.priceMatrix = priceMatrix;

}

public BigDecimal calculateTotalPrice(ShoppingCart cart) {

BigDecimal total = new BigDecimal("0.0");

for (Item item : cart.getItems()) {

total.add(priceMatrix.lookupPrice(item));

}

return total;

}

}

При цьому не потрібно навіть запитувати ресурс (об’єкт), framework сам дасть його.

Друга, більш популярна, техніка застосування Dependency Injection – setter-based injection. При ній для injection використовується set-метод. Приклад:

public class CashRegisterImpl implements CashRegister {

private PriceMatrix priceMatrix;

public setPriceMatrix(PriceMatrix priceMatrix) {

this.priceMatrix = priceMatrix;

}

public BigDecimal calculateTotalPrice(ShoppingCart cart) {

BigDecimal total = new BigDecimal("0.0");

for (Item item : cart.getItems()) {

total.add(priceMatrix.lookupPrice(item));

}

return total;

}

}

Framework неявно викликає setPriceMatrix – і програма автоматично отримує об’єкт для поля priceMatrix.

Для того, щоб Dependency Injection працювало, потрібно відповідні біни описати відповідним чином в файлі applicationContext.xml.

Application Context

The ApplicationContext є реалізацією BeanFactory, яка, в свою чергу, є реєстром всіх об’єктів, керованих Spring. Загалом, BeanFactory відповідає за створення бінів, зв’язування їх з залежними бінами і забезпечення засобів зручного пошуку бінів. ApplicationContext може розглядатися як повнофункціональна BeanFactory. ApplicationContexts також додає деякі додаткові можливості до BeanFactory. Він може автоматично обробляти BeanFactory після ініціалізації шляхом запуску BeanFactoryPostProcessors. Він також забезпечує можливість інтернаціоналізації, механізм маршрутизації повідомлень для слабо зв’язаних об’єктів і підтримує інтерфейси життєвого циклу, такі, як ApplicationContextAware.

ApplicationContext задається в файлі applicationContext.xml. Приклад:

<?xml version="1.0"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="cashRegister" class="org.example.CashRegisterImpl">

< property name="priceMatrix" ref="priceMatrixBean" />

</bean>

<bean id="priceMatrixBean" class="org.example.PriceMatrixImpl" />

</beans>

Plain Old Java Objects (POJO)

Отже, Dependency Injection та Spring Application Context є двома центральними концепціями в Spring Framework. Вони є інструментом забезпечення можливості побудови програми на основі виключно plain old Java objects (POJOs). Це дає можливість розробляти web-програми, які є повністю об’єктно-орієнтованими без прив’язки до конкретного framework всередині бізнес-логіки. Це дає змогу сфокусуватися на розробці бізнес-логіки вбудовану в model замість концентрації на специфічному для використовуваного framework коді. Це відчиняє двері для всіх  design patterns, принципів і практик ефективної об’єктно-орієнтованої розробки.

Інші конфігураційні файли

У web-програмі на основі Spring повинні бути ще файли web.xml та ім’я-servlet.xml. Приклад web.xml:

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"

xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>FirstSpringMVC</display-name>

<listener>

 <listener-class>

  org.springframework.web.context.ContextLoaderListener

 </listener-class>

</listener>

<servlet>

 <servlet-name>spring</servlet-name>

 <servlet-class>

  org.springframework.web.servlet.DispatcherServlet

 </servlet-class>

</servlet>

<servlet-mapping>

 <servlet-name>spring</servlet-name>

 <url-pattern>/app/*</url-pattern>

</servlet-mapping>

<welcome-file-list>

 <welcome-file>index.html</welcome-file>

 <welcome-file>index.jsp</welcome-file>

</welcome-file-list>

</web-app>

Елемент org.springframework.web.context.ContextLoaderListener потрібен для створення ApplicationContext, а org.springframework.web.servlet.DispatcherServlet перехоплює всі команди і перенаправляє в потрібному напрямку. Назва сервлета для DispatcherServlet (в цьому випадку spring) ставиться на перше місце в назві файлу ім’я-servlet.xml, тобто файл в цьому випадку повинен мати назву spring-servlet.xml. Приклад цього файлу:

<?xml version="1.0"?>

<!DOCTYPE beans PUBLIC

"-//SPRING//DTD BEAN//EN"

"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean name="/home"

 class="spring1.controller.FacultiesController">

 <property name="facultyDAO" ref="facultyDAO" />

</bean>

<bean id="viewResolver"

 class="org.springframework.web.servlet.view.InternalResourceViewResolver">

 <property name="prefix" value="/WEB-INF/jsp/" />

 <property name="suffix" value=".jsp"/>

</bean>

</beans>

В ньому зокрема описуються контролери і viewResolver'и – класи, що перетворюють логічні імена ресурсів відображення у їх фізичні імена.

Рівні абстракції в web-програмах

Оволодіння framework'ом – це не тільки вивчення API. Цілісне розуміння архітектури Spring MVC web-програми дає ключ до розуміння причин використання Spring і, таким чином, дозволяє приймати правильні рішення при побудові програми.

Spring-програма розділяється на рівні. Рівень – це блок з певною область відповідальності всередині програми. Рівні є абстракціями всередині програми і контракт взаємодії між ними встановлюється за допомогою інтерфейсів. Рівні мають концептуальні межі і не обов’язково розділені фізично. Найчастіше, всі рівні працюють в одній віртуальній машині.

Типова Spring MVC програма має п’ять рівнів абстракції, кожен з яких розробник повинен програмувати.

Рисунок. Рівні в Spring MVC програмі

Domain model перетинає всі інші рівні тому, що всі вони залежать від domain model.

Рівень UserInterface відповідає за взаємодію програми з кінцевим користувачем.

Web-рівень має два основних призначення – забезпечити логіку переміщення по сторінках програми та забезпечити з’єднання між service-рівнем та тим, що стосується http.

Service-рівень реалізує укрупнену функціональність програми. Він дає можливість виконати бізнес-дію за допомогою виклику одного методу.

Рівень Domain model реалізує більш детальну бізнес-логіку програми.

Persistence-рівень відповідає за взаємодію зі сховищем даних і забезпечує отримання і збереження об’єктів для Domain model.

Виокремлення доменів, таких, як persistence, web-навігація, user interface в окремі рівні дає можливість створювати гнучкі і легко тестовані програми. Реалізація кожного рівня може змінюватись незалежно, що підвищує гнучкість програми. Зменшення зв’язаності між різними областями в програмі підвищує тестованість, роблячи можливим протестувати кожну частину окремо. Така можливість забезпечується мінімізацією кількості залежностей між рівнями. Чим менше залежностей має рівень, тим дешевше його змінити. Добре, якщо рівень залежить тільки від одного чи двох інших рівнів. Потрібно уникати залежності якогось рівня в програмі від багатьох інших частин програми. Зростання рівня залежностей можна уникнути як мінімум двома шляхами. Якщо якийсь рівень має занадто багато зв’язків з іншими рівнями, потрібно розглянути можливість створення нового рівня абстракції. З іншого боку, якщо якийсь рівень проходить через всю програму (через багато інших рівнів), його можна представити як аспект системи і використати, наприклад, Spring AOP, при цьому усуваючи явні залежності в коді.


 

А также другие работы, которые могут Вас заинтересовать

55067. Грай, трембіто, дзвеніть, цимбали 533.5 KB
  Обладнання: кабінет образотворчого мистецтва зразки народних інструментів: трембіти роги цимбали; відеоматеріали. Тут грали і на скрипці і на сопілці особливо любили цимбали. У цій хаті жив і учився робити цимбали В.
55068. Всеукраїнська олімпіада з математики 795 KB
  Завдання: сформулювати і довести теореми Чеви і Менедая; показати їх застосування до доведення відомих і доведених раніше тверджень; вчити використовувати ці теореми під час розвязування задач на доведення і обчислення. Напередодні засідання учитель дає завдання трьом учням підготувати доведення тверджень про перетин в одній точці бісектрис внутрішніх кутів трикутника висот і медіан трикутника поділ кожної медіани їх точкою перетину на частини відношення довжин яких дорівнює 2:1 якщо вимірювати довжину першої частини від вершини....
55069. Позакласна робота з математики 223.5 KB
  Але вона має свої особливості: якщо урок проводиться за програмою то позакласні заняття не регламентуються нею що дозволяє вчителю підбирати завдання які відповідають рівню знань та умінь учнів здійснювати індивідуальний підхід проводити їх в цікавій формі спрямовувати на розширення поглиблення знань...
55070. Поняття про форми організації виховного процесу. Характеристика і методика проведення форм поза навчальної виховної роботи 63.5 KB
  Позакласна виховна робота - це здійснювана в позаурочний час різноманітна діяльність учнів під керівництвом учителіввихователів школи спрямована на задоволення інтересів і запитів розвиток їх інтелектуальних можливостей. Принципи на яких ґрунтується позакласна і позашкільна виховна робота Добровільний характер участі в ній учнів враховуються їх інтереси.
55071. Позакласне заняття. Весняні квіти з гофрованого паперу 34.5 KB
  Діти а для того щоб ви дізналися що ми будемо виготовляти сьогодні на занятті я вам пропоную відгадати загадки. Люблять її діти і дорослі за веселу пісеньку струмочків за дзвінкий спів птахів за ніжні проліски за мякий килим з шовкової травиці за ласкаве сонячне проміння за повітря напоєне запахом молодого листя. Діти тому сьогодні на занятті ми будемо виготовляти з паперу крокуси. Діти давайте повторимо послідовність нашої роботи.
55072. Письменники-лауреати Нобелівської премії 601 KB
  Мета: розповісти про засновника премії Альфреда Нобеля; ознайомити учнів з письменниками-лауреатами Нобелівської премії; сприяти перетворенню загальнолюдських цінностей в індивідуальний духовний досвід учнів; виховувати повагу до людської особистості, до скарбів культури; формувати гуманістичні ідеали добра.
55073. Інтелектуальне шоу «Брейн-ринг» 50 KB
  Мета: відновити в пам’яті учнів уявлення про фізичні та хвмвчні властивості хімічних речовин. Розвинути уміння працювати разом, розвинути логічне, творче мислення, увагу, пам’ять. Сформувати науковий світогляд. Виховати працелюбність, наполегливість, колективність в роботі, волю до подолання труднощів, повагу до думки іншого, інтерес до предмета.
55074. АНТРОПОНОМИНАНТЫ В РУССКОМ И ЧЕШСКОМ ЯЗЫКАХ: СЛОВООБРАЗОВАТЕЛЬНЫЙ АСПЕКТ 517 KB
  Определить критерии отбора антропономинантов; выделить из всех наименований лица антропономинанты со значением профессии, рода занятий, внешних и внутренних качеств человека; изучить словообразовательные способы и средства, по которым образуются наименования лица по профессии, роду занятий, по внешним и внутренним качествам человека;
55075. Исследование прав авторов и их гражданско-правовой защиты 439 KB
  Исследовать понятие авторского права и его компоненты, понятие исключительного права в контексте авторских прав, изучить проблему определения субъектов авторских прав в современной России, проанализировать вопрос определения объектов авторских прав как основополагающей правовой дефиниции при осуществлении авторских прав, дать анализ проблематике защиты имущественных прав авторов