Before advice

advertisement
Обзор возможностей
Инверсия управления
Аспектно-ориентированное
программирование
План презентации
1. Общие сведения о Spring Framework
2. Возможности Spring Framework
3. Инверсия управления (IoC)
4. Аспектно-ориентированное
программирование (АОП)
5. Spring и Tomcat
6. Контрольные вопросы
1. Общие сведения о Spring Framework
• Open Source
• Упрощает разработку enterpiseприложений (настройка, тестирование, …)
• Может применяться для web, десктопных,
мобильных приложений. (Есть android
версия)
• Платформы – Java, .Net (Spring.NET)
• Предоставляет богатый набор
вспомогательных классов
1. Общие сведения о Spring Framework
Официальный сайт
Spring Framework:
http://springsource.org
http://www.spring-source.ru/
http://www.javaportal.ru/java/articl
es/spring.html
http://habrahabr.ru/blogs/program
ming/114649
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 ShopService {
private MailService mail;
public ShopService() {
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) {
// выполняем отправку письма
}
}
public class ShopService {
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 – это контейнер, который:
• Хранит объекты, называемые бинами;
• Управляет их жизненным циклом;
• Позволяет задавать и разрешать
зависимости между ними используя
декларативный способ описания.
3. Инверсия управления (IoC)
Возможна подстановка зависимостей для любых
типов:
- коллекции (List, Map, Set, Properties)
- пользовательские классы
- примитивные и стандартные типы
Правила создания объектов и зависимостей
между ними описываются в
конфигурационном xml-файле, либо с
помощью специальных аннотаций.
3. Инверсия управления (IoC)
Преимущества:
1. Мы можем не указывать конкретные
реализации классов (например, для тестов
использовать заглушку MailServiceMock, в
реальных условиях использовать настоящий
класс MailServiceImpl)
2. Нет необходимости самостоятельно
управлять жизненным циклом объектов
3. При замене модулей не нужно
перекомпилировать приложение т.к. модули
соединяются декларативно
3. Инверсия управления (IoC)
Пример XML-конфигурации Spring:
<?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">
<import resource=“othersbeans.xml"/>
<bean id=“mailBean" class=“MailServiceImpl“ scope=“singleton” lazy-init="true"/>
<bean id=“basketBean" class=“BasketService“/>
<property name=“mail" ref=“mailBean" />
</bean>
</beans>
3. Инверсия управления (IoC)
Получение бинов из контейнера с помощью фабрики BeanFactory:
public interface BeanFactory {
containsBean(String name) ;
getBean(String name) ;
getType(String name) ;
isSingleton(String name) ;
}
Реализации – контексты Spring-приложений:
• ClassPathApplicationContext;
• WebApplicationContext;
• и др.
Пример использования бинов в обычном Java-приложении:
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)
Пример XML-конфигурации Spring, использующей аннотации для
описания бинов:
<?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">
<context:annotation-config />
<context:component-scan base-package="ru.spb.nicetu" />
</beans>
package ru.spb.nicetu.test;
@Component("testBean")
@Scope(“request”)
public class TestBean {
public TestBean() {
System.out.println("constructor");
}
}
3. Инверсия управления (IoC)
•
•
•
•
Варианты объявления бинов с помощью аннотаций:
@Service — сервисный слой, бизнес-логика и т.п.
@Repository — слой работы с БД
@Controller — слой работы с представлением
@Component —бин общего вида
•
•
•
•
Области видимости бинов (scope):
singleton – единственный экземпляр в приложении
prototype – на каждый запрос бина создаётся новый экземпляр
request - на каждый запрос от веб-клиента создаётся новый экземпляр
session - единственный экземпляр на время жизни сессии пользователя
*Примечание: подчеркнуты области видимости, применимые только к вебприложению.
3. Инверсия управления (IoC)
Управление жизненным циклом бинов:
Стиль аннотаций:
@Service(“myBean")
@Scope("session")
public class SimpleBean {
@Autowired
private TestBean bean;
@Autowired(required=false)
private OtherBean otherBean;
@PostConstruct
public void init() {
System.out.println(bean.getData());
}
public void setBean(TestBean bean) {
this.bean = bean;
}
}
@Autowired применим к полям, методам, конструкторам
3. Инверсия управления (IoC)
Стиль XML:
<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init" destroy-method="cleanup"/>
либо
<beans default-init-method="init" default-init-method=“destroy”>
<bean id="blogService" class="com.foo.DefaultBlogService"> <property name="blogDao" ref="blogDao" />
</bean>
</beans>
либо
public class AnotherExampleBean implements InitializingBean {
public void afterPropertiesSet() { // do some initialization work }
}
public class AnotherExampleBean implements DisposableBean {
public void destroy() { // do some destruction work (like releasing pooled connections) }
}
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() {
// ...
}
}
*В XML-конфигурацию необходимо добавить <aop:aspectj-autoproxy/> и подключить библиотеки AspectJ
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. Spring и Tomcat
1. Добавить в библиотеки веб-приложения библиотеки Spring
2. В web.xml приложения добавить:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
6. Контрольные вопросы
1. Что такое Spring? Какие возможности
предоставляет фреймворк?
2. Что такое инверсия управления? Зачем
она нужна?
3. Какую роль играет контейнер объектов в
Spring? Что такое Bean?
4. Что такое аспектно-ориентированное
программирование? Что такое аспект?
5. Перечислите четыре способа выполнения
аспектов в Spring.
Практическое задание
С помощью Spring написать программу, отправляющую сообщение,
введённое пользователем:
1) Подключить в проект необходимые для работы со Spring
библиотеки;
2) Создать интерфейс MessageSender с единственным методом
send(String text) и его реализацию MessageSenderImpl;
3) Создать веб-страницу с формой для ввода текста сообщения;
4) Создать класс MessageService, содержащий поле MessageSender и
методы get() и set();
5) Создать сервлет, обрабатывающий форму с текстом сообщения и,
используя класс MessageService, отправить сообщение;
6) Сформировать файл конфигурации для Spring, описать 2 созданных
класса: MessageSenderImpl и MessageService;
7) Запустить веб-сервер и проверить отправку сообщения;
8) Добавить в приложение аспект MyAspect, который перед отправкой
сообщения выводит в лог время отправки сообщения.
Download