The spring framework основи
Java: Статті The Spring framework: Основи
Зараз Spring це досить популярний opensource проект, що охоплює багато аспектів як J2EE, так і Java розробок.
Метою даної статті є опис архітектури та основних можливостей Spring.
архітектура
Архітектура Spring представлена наступною схемою

Мал. 1 Схема Spring
Далі в статті будуть розглянуті основні складові Spring Framework.
1. IoC контейнер
В основі Spring лежить патерн Inversion of control. Стосовно до легковажним контейнерів, основна ідея цього патерну полягає в усуненні залежності компонентів або класів додатки від конкретних реалізацій допоміжних інтерфейсів і делегування повноважень з управління створенням потрібних реалізацій IoC контейнеру. Розглянемо UML діаграму.
IoC контейнер відповідає за створення потрібної реалізації Product для Consumer. При використанні класу Consumer в інших проектах ми зможемо замінити реалізацію інтерфейсу Product на більш відповідну, не вносячи змін в код.
Основні переваги IoC контейнерів:- управління залежностями
- спрощення повторного використання класів або компонентів
- спрощення unit-тестування
- більш "чистий" код (Класи більше не займаються инициализацией допоміжних об'єктів. Не варто, звичайно "перегинати палицю", керуючи створенням абсолютно всіх об'єктів через IoC. В IoC контейнер найкраще виносити ті інтерфейси, реалізація яких може бути змінена в поточному проекті або в майбутніх проектах.)
Патерн IoC не єдиний, що дозволяє усунути залежність від реалізації. Альтернативою IoC є, добре відомі шаблони ServiceLocator / Factory.

Мал. 3 Шаблон ServiceLocator Даний підхід вносить залежність коду від ServiceLocator, що призводить до меншої гнучкості. Основні недоліки шаблону ServiceLocator:
- Якщо в одному проекті в різних випадках будуть потрібні різні реалізації Product, доведеться або міняти код виклику ServiceLocator у всіх використовуваних місцях, вказуючи додаткові параметри або змінювати сам ServiceLocator. Обидва варіанти призводять до "засмічення" коду, внесення додаткових умов і параметрів, які ускладнюють код і його повторне використання.
- При використанні коду в інших проектах
- (ServiceLocator поширюється разом з кодом) У випадку, коли для отримання потрібної реалізації Product будуть потрібні додаткові параметри доведеться вносити зміни в поставляється ServiceLocator. Це ще призводить до існування в системі декількох ServiceLocator, кожен з яких необхідно по-своєму налаштовувати, що ускладнює супровід.
- (ServiceLocator не поставляється з кодом) В цьому випадку доведеться змінювати виклик ServiceLocator на використовуваний в даній системі. Введення загального інтерфейсу так само не вирішує проблеми.
Найпоширеніший спосіб вказівки залежностей це XML файли конфігурації (applicationContext.xml). Опис формату цього файлу виходить за рамки даної статті.
Spring набагато більше, ніж просто IoC контейнер. Framework спрощує розробку J2EE проектів, реалізуючи низькорівневі і найбільш часто іcпользуемие частини корпоративного програми.
Одним з ключових компонентів Spring є AOP framework. Навіть не використовуючи AOP безпосередньо ви, швидше за все, зіткнетеся з ним опосередковано.
Основні завдання, які вирішуються за допомогою AOP в Spring:- Декларативне управління транзакціями.
- Організація пулів об'єктів.
- Написання власних аспектів.
Найбільш зручний і гнучкий спосіб управління транзакціями це декларативне управління транзакціями. Якщо ви раніше працювали з EJB CMT, то прекрасно уявляєте що це таке. Декларативне управління транзакціями позбавляє код від залежності від фреймворка або конкретного механізму управління транзакціями.
Конфігураційний файл (applicationContext.xml) виглядає наступним чином:
Об'єкт myService це вже транзакційний MyBusinessObject, доступ до нього здійснюється через Proxy (TransactionProxyFactoryBean), який і керує транзакціями. Для користувача не буде ніякої різниці, що робота з Proxy, що робота з MyBusinessObject безпосередньо. Є й інший спосіб опису транзакционной конфігурації, через BeanNameAutoProxyCreator. Даний спосіб дозволяє скоротити розмір конфігураційного файлу. Для більш детальної інформації зверніться до документації.
Організація пулів об'єктів застосовується і в EJB. Контейнер підтримує пул stateless session EJB, при виклику методу об'єкт звільняється з пулу. При використанні Spring, пул об'єктів може підтримуватися для будь-яких POJO (Plain Old Java Object). Приклад конфігураційного файлу:
AOP допомагає усунути дублювання коду. Java це об'єктно-орієнтована мова, який дозволяє створювати ієрархії взаємозалежних об'єктів. Але як бути, якщо один і той же код використовується в різних ієрархіях об'єктів?
Будь-який додаток можна розглядати з двох позицій. З точки зору функціональності окремих класів (core concerns) і функціоналу охоплює всі додаток (crosscutting concerns). Модулі, що управляють crosscutting concerns, називаються аспектами. В Spring аспекти реалізуються через Advisors і Interceptors.
Аспекти можуть вирішувати такі завдання: логирование, кешування, управління безпекою, транзакції і т.д. Введення додаткового шару інтерцепторів розмежовує відповідальність між основним кодом і допоміжними завданнями. В результаті спрощується супровід коду і його повторне використання. Інтерцептори конфигурируются незалежно, вони можуть використовуватися в інших проектах, в свою чергу об'єкти можуть конфигурироваться з різними інтерцепторами.
Як приклад візьмемо завдання - визначення часу виконання методів. Це може бути корисно для виявлення вузьких місць, як під час тестування, так і на production при реальну кількість користувачів на реальних даних.
Зверніть увагу на інтерфейс org.aopalliance.intercept.MethodInterceptor. Це інтерфейс AOP Alliance. Відповідно такі інтерцептори стерпні в інші AOP frameworks. В Spring є свої власні інтерфейси інтерцепторів, призначені для різних випадків. У даній статті ці інтерфейси не розглядаються.
MethodInterceptor надає найбільш повний контроль над процесом виконання. Для нашої задачі підходить саме цей інтерфейс.
У рядку 12 відбувається виклик наступного Інтерцептор в ланцюжку або методу основного об'єкта. Зауважте, для того, що б PerformanceInterceptor надавав найбільш точну інформацію про час виконання методу він повинен бути останнім у ланцюжку.
Тепер залишилося тільки змінити конфігураційний файл.
Додаткові можливості
Як вже було сказано раніше, Spring крім IoC контейнера включає в себе безліч класів, що реалізують найбільш затребуваний функціонал J2EE додатків. Spring істотно спрощує роботу з JDBC, ORM frameworks, EJB, Web services. Framework реалізує вищий рівень абстракції управління розсилкою пошти, кешуванням, виконання завдань за розкладом. Крім цього Spring включає в себе ще й Web framework.
Малоймовірно, що в додатку, що розробляється будуть використовуватися всі можливості Spring. Тому ви можете включати в додаток тільки ті jar-архіви, класи яких ви використовуєте. Spring групує класи в jar по пакетам: spring-aop.jar, spring-beans.jar і т.д. Ви так само можете включити один jar з усіма класами - spring.jar.
Далі будуть описані деякі з можливостей Spring Framework.
Почнемо відразу з прикладу.
Більше не потрібно писати громіздкі конструкції try catch (..) finally, управляти з'єднаннями, транзакціями. Прості запити взагалі вміщаються в один рядок.
Интернализация (i18n) і конфігурація
Spring включає класи і інтерфейси, призначені для інтерналізації додатки. Всі повідомлення зберігаються в properties файлах. Один properties файл відповідає одній мові. Для того, що б отримати доступ до цих повідомлень, в applicationContext.xml необхідно додати messageSource бін. Ім'я messageSource є обов'язковим. Spring підтримує ієрархічні повідомлення.
В інтерфейсі ApplicationContext (основний інтерфейс, який визначає конфігурацію додатка) є відповідні методи getMessage (MessageSourceResolvable resolvable, Locale locale), getMessage (String code, Object [] args, Locale locale), getMessage (String code, Object [] args, String defaultMessage, Locale locale). Приклад використання:
Всі конфігураційні параметри програми зручно зберігати в одному або декількох properties файлах. До них можна буде звертатися прямо з applicationContext.xml. Для цього в applicationContext.xml потрібно додати бін.
Тоді до параметрів можна буде звертатися в такий спосіб.
Де jdbc.jndiName конфігураційний параметр в WEB-INF / config.properties.
Обробка подій в Spring здійснюється через клас ApplicationEvent і інтерфейс ApplicationListener. При настанні події нотифікує всі об'єкти, що реалізують інтерфейс ApplicationListener. Розглянемо приклад.
Виклик context.publishEvent () відбувається в синхронному режимі. Все ApplicationListener виконуються в тому ж транзакційному контексті, що і EventPublisher.
висновок
У статті були розглянуті базові принципи і деякі з можливостей Spring. Для більш детального вивчення рекомендую прочитати книгу Spring in Action і документацію, що входить в дистрибутив.
До основних переваг Spring відносяться: простота; зручність тестування; використання Spring позитивно позначається на дизайні додатки і простоті коду.
В Spring реалізовано багато без чого не обходиться практично будь-яке Java програма. Перш ніж винаходити, щось своє подивіться, можливо, це вже є в Spring.
Warning. mysql_connect () [function.mysql-connect]: Can not connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/books/show2b.php on line 11
Warning. mysql_db_query () [function.mysql-db-query]: Can not connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/books/show2b.php on line 19
Warning. mysql_db_query () [function.mysql-db-query]: A link to the server could not be established in /pub/home/javaport/javaportal/books/show2b.php on line 19
Warning. mysql_fetch_array (): supplied argument is not a valid MySQL result resource in /pub/home/javaport/javaportal/books/show2b.php on line 30
Дізнайся про що ти насправді зараз думаєш тут.
[An error occurred while processing this directive]
Warning. mysql_connect () [function.mysql-connect]: Can not connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/news/worldnews.php on line 91
Warning. mysql_db_query () [function.mysql-db-query]: Can not connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/news/worldnews.php on line 93
Warning. mysql_db_query () [function.mysql-db-query]: A link to the server could not be established in /pub/home/javaport/javaportal/news/worldnews.php on line 93
Warning. mysql_fetch_array (): supplied argument is not a valid MySQL result resource in /pub/home/javaport/javaportal/news/worldnews.php on line 95