codefest 2011. Крестьянинов М. — Обзор...
TRANSCRIPT
![Page 1: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/1.jpg)
Знакомство с аспектно-ориентированнымпрограммированием
Михаил Крестьянинов,Новотелеком
![Page 2: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/2.jpg)
Эволюция парадигм
2
![Page 3: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/3.jpg)
Сферический быдлокод в вакууме
public class WebService {
public BookDTO getBook(Integer bookId) {
BookDTO book = bookDAO.readBook(bookId);
return book; }
}
3
![Page 4: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/4.jpg)
Сферический быдлокод:Логирование
public BookDTO getBook(Integer bookId) {
LOG.debug("Call method getBook with id " + bookId);
BookDTO book = bookDAO.readBook(bookId);
LOG.debug("Book info is: " + book.toString()); return book;}
4
![Page 5: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/5.jpg)
Сферический быдлокод:Обработка исключенийpublic BookDTO getBook(Integer bookId) throws ServiceException {
LOG.debug("Call method getBook with id " + bookId); BookDTO book = null; try { BookDTO book = bookDAO.readBook(bookId); } catch(SQLException e) { throw new ServiceException(e); }
LOG.debug("Book info is: " + book.toString()); return book;}
5
![Page 6: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/6.jpg)
Сферический быдлокод:Авторизацияpublic BookDTO getBook(Integer bookId)
throws ServiceException, AuthException {
if (!SecurityContext.getUser().hasRight("GetBook")) throw new AuthException("Permission Denied");
LOG.debug("Call method getBook with id " + bookId); BookDTO book = null; try { BookDTO book = bookDAO.readBook(bookId); } catch(SQLException e) { throw new ServiceException(e); }
LOG.debug("Book info is: " + book.toString()); return book;}
6
![Page 7: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/7.jpg)
Сферический быдлокод:Кеширование
public BookDTO getBook(Integer bookId) throws ServiceException, AuthException {
if (!SecurityContext.getUser().hasRight("GetBook")) throw new AuthException("Permission Denied");
LOG.debug("Call method getBook with id " + bookId); BookDTO book = null; String cacheKey = "getBook:" + bookId; try {
if (cache.contains(cacheKey)) { book = (BookDTO) cache.get(cacheKey); } else { BookDTO book = bookDAO.readBook(bookId);
cache.put(cacheKey, book); } } catch(SQLException e) { throw new ServiceException(e); }
LOG.debug("Book info is: " + book.toString()); return book;}
7
![Page 8: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/8.jpg)
Сферический быдлокод:Идеальный вариант
8
![Page 9: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/9.jpg)
Сквозная функциональность
• логирование;
• профилирование;
• обработка транзакций;
• обработка ошибок;
• авторизация и проверка прав;
• кеширование;
• контрактное программирование.
9
![Page 10: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/10.jpg)
Что такое АОП
Основной задачей аспектно-ориентированного программирования (АОП) является модуляризация сквозной функциональности, выделение её в аспекты.
10
![Page 11: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/11.jpg)
AspectJ: Пример аспекта@Aspectpublic class WebServiceLogger { private final static Logger LOG = Logger.getLogger(WebServiceLogger.class);
@Pointcut("execution(* example.WebService.*(..)) && @annotation(example.Loggable)") public void loggableMethod() { }
@Around(“loggableMethod()") public Object logWebServiceCall(ProceedingJoinPoint thisJoinPoint) { String methodName = thisJoinPoint.getSignature().getName(); Object[] methodArgs = thisJoinPoint.getArgs();
LOG.debug("Call method " + methodName + " with args " + methodArgs); Object result = thisJoinPoint.proceed(); LOG.debug("Method " + methodName + " returns " + result); return result; }}
11
![Page 12: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/12.jpg)
Термины АОП
• аспект (aspect);
• совет (advice);
• точка соединения (join point);
• срез (pointcut);
• внедрение (introduction).
12
![Page 13: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/13.jpg)
AspectJ: точки соединения
Создание объекта
• initialization(MyClass || MyOtherClass);
• staticinitialization(MyClass+ && !MyClass);
Вызов метода, обращение к свойству
• execution(static * com.xyz..*.*(..));
• call(void MyInterface.*(..));
• handler(ArrayOutOfBoundsException);
• get/set(static int MyClass.x);
13
![Page 14: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/14.jpg)
AspectJ: точки соединения
Вспомагательные
• this/target(MyClass)
• args(Integer)
• within/withincode(MyClass)
• cflow/cflowbelow(call(void MyClass.test()))
• @annotation(MyAnnotation)
14
![Page 15: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/15.jpg)
AspectJ: советы
• before – запуск совета до выполнения точки соединения;
• after returning — запуск совета после нормального выполнения точки соединения;
• after throwing — запуск совета после выброса исключения в процессе выполнения точки соединения;
• after — запуск совета после любого варианта выполнения точки соединения;
• around – запуск совета вместо выполнения точки соединения (выполнение точки соединения может быть вызвано внутри совета).
15
![Page 16: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/16.jpg)
AspectJ: вторая попытка
@Aspectpublic class WebServiceLogger { private final static Logger LOG = Logger.getLogger(WebServiceLogger.class);
@Pointcut("execution(* example.WebService.*(..)) && @annotation(example.Loggable)") public void loggableMethod() { }
@Around(“loggableMethod()") public Object logWebServiceCall(ProceedingJoinPoint thisJoinPoint) { String methodName = thisJoinPoint.getSignature().getName(); Object[] methodArgs = thisJoinPoint.getArgs();
LOG.debug("Call method " + methodName + " with args " + methodArgs); Object result = thisJoinPoint.proceed(); LOG.debug("Method " + methodName + " returns " + result); return result; }}
16
![Page 17: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/17.jpg)
PostSharpАспект обработки исключений:
public class ExceptionDialogAttribute : OnExceptionAspect{ public override void OnException(MethodExecutionEventArgs e) { string message = e.Exception.Message; Window window = Window.GetWindow((DependencyObject)eventArgs.Instance);
MessageBox.Show(window, message, "Exception");
eventArgs.FlowBehavior = FlowBehavior.Continue; }}
17
![Page 18: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/18.jpg)
PostSharp
Применение аспекта через настройки сборки:
[assembly: ExceptionDialog ( AttributeTargetTypes="Example.WorkflowService.*", AttributeTargetMemberAttributes = AttributeTargetElements.Public )]
Применение аспекта с помощью атрибута:
[ExceptionDialog]public BookDTO GetBook(Integer bookId)
18
![Page 19: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/19.jpg)
PostSharp
Aспекты:
• OnMethodBoundary/OnMethodInvocation – обращение к методу (начало, конец, выход, выход с исключением);
• OnFieldAccess – обращение к свойству;
• OnException – обработка исключения;
• Composition – внедрение кода.
19
![Page 20: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/20.jpg)
Как это работает?
20
![Page 21: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/21.jpg)
Как это работает?
• Изменение байт-кода:
21
![Page 22: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/22.jpg)
Как это работает?
• Автоматическое создание proxy-объектов:
22
![Page 23: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/23.jpg)
От теории к практике
23
![Page 24: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/24.jpg)
От теории к практике
24
![Page 25: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/25.jpg)
От теории к практике
• Отталкивает необходимость использования дополнительных компиляторов;
• Смущает отсутствие широкой известности и большого сообщества.
26
![Page 26: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/26.jpg)
Spring AOP
• написан на чистом Java/C#;
• не использует сторонних компиляторов;
• урезанная поддержка АОП;
• интеграция с AspectJ;
• поддержка аннотаций @AspectJ;
• часть Spring Framework.
26
![Page 27: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/27.jpg)
Spring AOP: Примеры
Ограничение прав доступа:
<sec:protect-pointcut expression="execution(* ru.novotelecom.xxx.Subscription.*(..))" access="ROLE_SUBSCRIPTION_MANAGER" />
Или
@Aspectpublic class SecurityManager {
@Before("execution(* ru.novotelecom.xxx.Subscription.*(..))") public void doAccessCheck() {… }}
27
![Page 28: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/28.jpg)
Spring AOP: ПримерыОбработка исключений:
@Aspectpublic class WebServiceException {
@Pointcut("execution(* example.WebService.*(..)) && @annotation(example.Loggable)") public void loggableMethod() { }
@Around(“loggableMethod()") public Object logWebServiceCall(ProceedingJoinPoint thisJoinPoint) throws ServiceException { Object result = null;
try { result = thisJoinPoint.proceed(); } catch (Exception e) { throw new ServiceException(e); }
return result; }}
28
![Page 29: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/29.jpg)
Альтернативы
Шаблоны проектирования:
• Proxy
• Decorator
• Chain of responsibility
Конструкции языка:
• Аннотации / Атрибуты
29
![Page 30: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/30.jpg)
АОП в других языках
• python (Aspyct)
• perl (Aspect CPAN)
• ruby (AspectR)
• c++ (AspectC++)
• php (Seasar, GAP)
• javascript (Ajaxpect)
30
![Page 31: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/31.jpg)
Резюме
• Основная цель АОП — выноса «общей» (сквозной) функциональности «за скобки» (модуляризация сквозной функциональности);
• Для Java AOP доступен через проект AspectJ, для .NET – через PostSharp;
• Наиболее простая и проверенная реализация AOP – Spring AOP.
31
![Page 32: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/32.jpg)
От теории к практике
32
![Page 33: CodeFest 2011. Крестьянинов М. — Обзор аспектно-ориентированного программирования](https://reader035.vdocument.in/reader035/viewer/2022081504/558788b3d8b42a4c318b461d/html5/thumbnails/33.jpg)
Ссылки
• http://habrahabr.ru/blogs/programming/114649/
• http://www.eclipse.org/aspectj/
• http://www.sharpcrafters.com/postsharp
• https://www.ibm.com/developerworks/ru/library/j-aopwork15/
• http://en.wikipedia.org/wiki/Aspect-oriented_programming
33