Обзор возможностей Инверсия управления Аспектно-ориентированное программирование План презентации 1. Общие сведения о Spring Framework 2. Возможности Spring Framework 3. Инверсия управления (IoC) 4. Аспектно-ориентированное программирование (АОП) 5. Контрольные вопросы 1. Общие сведения о Spring Framework • Open Source • Упрощает разработку enterpiseприложений (настройка, тестирование, …) • Может применяться для web, десктопных, мобильных приложений. (Есть android версия) • Платформы – Java, .Net (Spring.NET) • Предоставляет богатый набор вспомогательных классов 1. Общие сведения о Spring Framework Официальный сайт Spring Framework: springsource.org 1. Общие сведения о Spring Framework 2. Возможности Spring • Инверсия управления (Inversion of Control) • Аспектно-ориентированное программирование • Spring – это контейнер объектов, нет необходимости писать в коде new, вместо этого запрашиваем объекты у него • Spring – это фреймворк, который содержит библиотеки для web, orm, security, aop, ioc, mail, remoting – он предоставляет интерфейсы для абстрагирования от этих сервисов 3. Инверсия управления (IoC) public class MailService { public void send(String from, String to, String subject, String text) { // выполняем отправку письма } } public class BasketService { private MailService mail; public BasketService() { mail = new MailService(); } public void makeOrder() { // Сохраняем заказанные товары // Отправляем письмо mail.send(“shop@shop.com”, “customer@customer.com”, “Заказ принят”); } } 3. Инверсия управления (IoC) • В системе много объектов, которые определённым образом между собой связаны (например, вызывают друг друга) • Если мы указываем зависимости в коде: - трудно тестировать классы по отдельности - трудно подменять классы для разных конфигураций • Мы можем выделить интерфейс и соединить объекты с помощью set-метода 3. Инверсия управления (IoC) public interface MailService { public void send(String from, String to, String subject, String text) ; } public class MailServiceImpl implements MailService{ public void send(String from, String to, String subject, String text) { // выполняем отправку письма } } В конфигурационном Spring указывается файле public class BasketService { реализация интерфейса private MailService mail; public void setMailService(MailService mail) { this.mail = mail; } public void makeOrder() { // Сохраняем заказанные товары и отправляем письмо mail.send(“shop@shop.com”, “customer@customer.com”, “Заказ принят”); } } 3. Инверсия управления (IoC) • В любом случае мы должны установить зависимости в коде и указывать конкретные реализации классов • Решение проблемы – переложить работу по установлению зависимостей на Spring 3. Инверсия управления (IoC) Spring – это контейнер, который: • Управляет жизненным циклом объектов • Позволяет настроить, как он будет их выдавать: - синглтон - новый объект - пул объектов • Позволяет настроить их автоматическое удаление • Позволяет задать зависимости между ними (подстановка (injection) зависимостей) • Spring IoC – основной модуль Spring 3. Инверсия управления (IoC) Возможна подстановка зависимостей для любых типов: - коллекции (List, Map, Set, Properties) - пользовательские классы - примитивные и стандартные типы Правила создания объектов и зависимостей между ними описываются в конфигурационном xml-файле 3. Инверсия управления (IoC) <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=http://www.springframework.org/schema/beans xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id=“mailBean" class=“MailServiceImpl“/> <bean id=“basketBean" class=“BasketService“/> <property name=“mail" ref=“mailBean" /> </bean> </beans> public class Main { public static void main(String args[]) { ApplicationContext context = new ClassPathApplicationContext(“spring-beans.xml”); BasketService service= (BasketService ) context.getBean(“basketBean”); service.makeOrder(); } } 3. Инверсия управления (IoC) Преимущества: 1. Мы можем не указывать конкретные реализации классов (например, для тестов использовать заглушку MailServiceMock, в реальных условиях использовать настоящий класс MailServiceImpl) 2. Нет необходимости самостоятельно управлять жизненным циклом объектов 3. При замене модулей не нужно перекомпилировать приложение т.к. модули соединяются декларативно 3. Инверсия управления (IoC) • Контейнеров может быть несколько • Процедура создания контейнера зачастую занимает много времени – не рекомендуется создавать много контейнеров • Обычно создаётся один контейнер для одного приложения 4. Аспектно-ориентированное программирование • Существует такая функциональность, которая не относится к каким-либо модулям системы – Логирование – Проверка прав доступа – Вызов метода в рамках транзакции – Обработка исключительных ситуаций • С помощью АОП мы можем подключаться в определённые места программы и вставлять нужный нам код 4. Аспектно-ориентированное программирование • Классы, которые описывают такой функционал, называются аспектами • В Spring существует своя реализация АОП • Она подходит для реализации задач средней сложности • Для более сложных - разработчики Spring рекомендуют использовать библиотеку AspectJ 4. Аспектно-ориентированное программирование Spring поддерживает четыре способа выполнения аспектов: • Before advice – перед выполнением метода; • After returning advice – после того, как метод возвратит результат; • After throwing advice – после того, как метод создаст исключительную ситуацию; • Around advice – комбинация трёх вышеперечисленных способов. 4. Аспектно-ориентированное программирование import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class BeforeExample { @Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation()") public void doAccessCheck() { // ... } @AfterReturning ("execution(* com.xyz.myapp.dao.*.*(..))") public void doAccessCheck() { // ... } @AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()") public void doRecoveryActions() { // ... } } 4. Аспектно-ориентированное программирование Возможные способы связывания аспектов с кодом с помощью выражения execution: execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?) – формат выражения execution 1. execution(public * *(..)) – вызов аспекта после выполнения любого publicметода; 2. execution(* set*(..)) – вызов аспекта после выполнения любого метода, название которого начинается с set; 3. execution(* com.xyz.service.AccountService.*(..)) – вызов аспекта после выполнения любого метода класса com.xyz.service.AccountService; 4. execution(* com.xyz.service.*.*(..)) – вызов аспекта после выполнения любого метода из пакета service; 5. execution(* com.xyz.service..*.*(..)) - вызов аспекта после выполнения любого метода из пакета service и всех его подпакетов. 5. Контрольные вопросы 1. Что такое Spring? Какие возможности предоставляет фреймворк? 2. Что такое инверсия управления? Зачем она нужна? 3. Какую роль играет контейнер объектов в Spring? Что такое Bean? 4. Что такое аспектно-ориентированное программирование? Что такое аспект? 5. Перечислите четыре способа выполнения аспектов в Spring.