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, при цьому усуваючи явні залежності в коді.


 

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

22135. Вытяжка без утонения 314 KB
  Схема операции – вытяжка из осесимметричной полой заготовки. При этом величина зазора между матрицей и пуансоном составляет не менее толщины исходной листовой заготовки Рис. Пример заготовки и детали.
22136. Вытяжка с утонением стенки 165 KB
  Механическая схема деформации и распределение деформации по очагу пластической деформации. Степень деформации при вытяжке оценивают коэффициентом вытяжки: или см. Частицы расположенные у нижней границы очага пластической деформации получают максимальную деформацию: . Частицы расположенные у верхней границы очага пластической деформации получают минимальную деформацию.
22137. Волочение 197 KB
  а б Рис. Рис. Допущения: напряжённое состояние плоское; продольные скорости металла одинаковы в пределах поперечного сечения ОПД очаг пластической деформации; и считаем главными напряжениями Сечениями z и zdz выделим элемент ОПД Рис. Рис.
22138. Метод верхней оценки 162.5 KB
  Сущность метода верхней оценки заключается в разбиении заготовки на жесткие блоки наделённые возможностью относительного скольжения и составлении баланса мощностей внешних и внутренних сил. При этом мощность пластической деформации рассчитывается как сумма мощностей сил трения по всем поверхностям скольжения жестких блоков относительно друг друга и инструмента. Скорости скольжения рассчитываются путём построения годографа скоростей. Строят годограф скоростей и определяют все скорости относительного скольжения всех блоков.
22139. Вырубка и пробивка 183 KB
  В верхнем небольшом по толщине слое металла примыкающем к пуансону. В нижнем небольшом по толщине слое металла прилегающем к матрице. 4 В срединном слое металла наибольшом по толщине двухосная схема напряжений и схема деформации сдвига. Местное поверхностное смятие развивается по толщине пока вся толщина металла не будет охвачена пластической деформацией; на третьей стадии происходит пластическая деформация в узкой по толщине кольцевой зоне пластический сдвиг.
22140. Прошивка 333 KB
  Схема открытой прошивки: а – сквозная прошивка высокой заготовки; б – сквозная прошивка высокой заготовки после поворота заготовки на 180;1 – нижняя плита; 2 – противень; 3 4 – первая и вторая проставки; 5 – боек; 6 – заготовка; в – сквозная прошивка низкой заготовки; 7 – подставка; 8 – подкладное кольцо; 9 – низкая подставка; 10 – выдра; 11 – исходная заготовка. При открытой прошивке боковая поверхность заготовки является свободной см. При открытой прошивке исходная форма заготовки искажается hD неравномерно. Искажение при открытой...
22141. Обжим, раздача, отбортовка 298.5 KB
  P S 3 2 S 1 Рис 1. Рис. P v S 3 2 S 1 Рис. Рис.
22142. Энергосиловые параметры операций ОМД 177.5 KB
  Расчёт мгновенного значения силы деформирования. Удельная сила деформирования. Силой деформирования называют результирующую силу элементарных сил действующих со стороны штампа на металлическую заготовку.
22143. Механические схемы деформаций 105.5 KB
  Схемы напряжений. Как изменяется НДС одной и той же частицы во времени показывают: траектория деформирования; траектория нагружения; графическая зависимость показателя жесткости схемы напряжений – K от времени; графическая зависимость показателя Лоде для напряжений νσ от времени для для деформаций ν от времени. Аналогично можно представить шестимерное пространство напряжений. Вектор напряжений координаты конца которого равны σx σy σz τxy τyz τzx опишет пространстве напряжений линию называемую траекторией нагружения.