Download - Programowanie aspektowe
Projektowanie warstwy serwera
Programowanie aspektowe
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
2Projektowanie warstwy serwera Programowanie aspektowe
• Metoda programowania mająca na celu modularyzację kodu i likwidację nakładających się problemów przekrojowych
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
3Projektowanie warstwy serwera AOP - przykłady zastosowania
– logowanie, profilowanie, cacheowanie– autoryzacja i uwierzytelnianie– zarządzanie błędami, transakcje– sprawdzanie poprawności danych– rejestracja zmian
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
4Projektowanie warstwy serwera AOP – podstawowe pojęcia (I)
• Aspekt - wydzielona funkcjonalnie cześć programu, realizująca konkretne zadanie i koncentrująca sie tylko na problemie, którego dotyczy (np. logowanie, monitorowanie aplikacji, zarządzanie transakcjami).
• Podstawowe pojęcia AOP– aspekt (aspect): nazwany problem przekrojowy, inaczej
to zbiory rad i punktów cięć/złączeń– rada (advice): dodatkowe zachowanie/czynność które
zostaje zaninicjowane w punkcie złączenia,– punkt złączenia (join point): miejsce w strukturze
wykonywania się aplikacji w którym powinna zostać zastosowana rada.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
5Projektowanie warstwy serwera AOP – podstawowe pojęcia (II)
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
6Projektowanie warstwy serwera Spring AOP framework
• Rodzaje rad:– around advice: wykonuje się przed i po punkcie styku,
ma możliwość przerwania przepływu kontroli programu przez zwrócenie własnej wartości lub wyjątku,
– before advice: wykonuje się przed punktem styku, nie może zablokować przepływu kontroli programu,
– throws advice: wykonuje się w momencie zgłoszenia wyjątku,
– after returning advice: wykonuje się po poprawnym wykonaniu.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
7Projektowanie warstwy serwera Around Advice
• Zgodność z AOP Alliance.• Przechwycenie wywołania metody.• Może zastąpić Before, After oraz Throws Advice.• Możliwość zatrzymania wywołania metody.• Możliwość zwrócenia innego obiektu niż
przechwycona metoda.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
8Projektowanie warstwy serwera Before Advice
• Wplatany przed wywołaniem metody.
• Zatrzymanie wykonania metody tylko poprzez wyrzucenie wyjątku.
• Ograniczone możliwości modyfikacji parametrów wywołania metody.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
9Projektowanie warstwy serwera After Advice
• Wplatany przy udanym powrocie z metody.
• Ograniczone możliwości zmiany wyniku zwróconego przez metodę.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
10Projektowanie warstwy serwera Throws Advice
• Wplatany w przypadku wyrzucenia wyjątku przez metodę.
• Możliwość zaimplementowania różnych metod dla różnych wyjątków w jednej klasie.
• Brak możliwości „zatrzymania” wyjątku.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
11Projektowanie warstwy serwera Implementacja (I)
public class TracingBeforeAdvice implements MethodBeforeAdvice
{
public void before(Method m, Object[] args, Object target) throwsThrowable
{
System.out.println("Before method : "+ m.getName() );
}
}
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
12Projektowanie warstwy serwera Implementacja (II)
public class TracingAfterAdvice implements AfterReturningAdvice
{
public void afterReturning(Object object, Method m, Object[] args, Object target) throwsThrowable
{
System.out.println("After method : "+ m.getName());
}
}
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
13Projektowanie warstwy serwera Konfiguracja (I)
<bean id=”proxybean"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="beanTarget" />
</property>
<property name="interceptorNames">
<list>
<value>theTracingBeforeAdvisor</value>
<value>theTracingAfterAdvisor</value>
</list>
</property>
</bean>
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
14Projektowanie warstwy serwera Konfiguracja (II)
<bean id="theTracingBeforeAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="theTracingBeforeAdvice" />
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>
<bean id="theTracingBeforeAdvice" class="TracingBeforeAdvice" />
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
15Projektowanie warstwy serwera Przykład
public class TimeInterceptor implements MethodInterceptor
{
public Object invoke(MethodInvocation method) throwsThrowable
{
long start = System.currentTimeMillis();
try { Object result= method.proceed();
return result; }
finally {
long end= System.currentTimeMillis();
long timeMs= end-start;
System.out.println("Method: " + method.toString() + " took: " + timeMs+"ms.");
}}}
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
16Projektowanie warstwy serwera @Aspect
@Aspect
public class MyAspect
{
.....
}
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
17Projektowanie warstwy serwera @Pointcut
@Pointcut("execution(* transfer(..))")
private void my()
{}
• execution• target• args
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
18Projektowanie warstwy serwera execution
• execution(public * *(..))• execution(* set*(..))• execution(* com.xyz.service.*.*(..))• execution(* com.xyz.service..*.*(..))• execution (public * dao.commons..*.update(..)))
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
19Projektowanie warstwy serwera Stosowane adnotacje
• @Before()• @AfterReturning(Object)• @AfterThrowing(Exception)• @After()• @Around(ProceedingJoinPoint)
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
20Projektowanie warstwy serwera @Around
@Around("execution(* dao..*.get(..))")
public Object applySecurity(ProceedingJoinPoint joinpoint) throws Throwable
{
logger.debug("Applying Security");
Object obj = joinpoint.proceed();
.....
return obj;
}
}
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
21Projektowanie warstwy serwera Przykład
@Aspect
public class DataUpdateInterceptor
{
@After("(execution(public *dao.commons..*.update(..)) || "
+ "execution(public *dao.commons..*.save(..)) ) && "
+ " target(dao.GenericDAO)")
public void updateDataAspect(JoinPoint jp)
{
logger.debug("nastapila zmiana w danych");
}
}
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
22Projektowanie warstwy serwera Konfiguracja
<aop:aspectj-autoproxy/>
<bean class=”common.DataUpdateInterceptor ">
</bean>
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
23Projektowanie warstwy serwera @Auditable
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Auditable
{
}
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
24Projektowanie warstwy serwera @NonAuditableField
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NonAuditableField
{
}
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
25Projektowanie warstwy serwera Klasa domenowa
@Auditable
@Entity
public class Uzytkownik
{
....
@NonAuditableField
@Column(nullable = true, length = 64)
private String haslo;
....
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
26Projektowanie warstwy serwera AudytInterceptor (I)
@Transactional(propagation = Propagation.MANDATORY)
public class AudytInterceptor extends EmptyInterceptor
{
private AuditLoggerService auditLoggerService;
...
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
27Projektowanie warstwy serwera AudytInterceptor (II)
@Override
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
{
if (entity.getClass().isAnnotationPresent(Auditable.class))
{
auditLoggerService.logSave(entity, id, state, propertyNames, types);
}
return super.onSave(entity, id, state, propertyNames, types);
}
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
28Projektowanie warstwy serwera AudytInterceptor (III)
@Override
public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
{
if (entity.getClass().isAnnotationPresent(Auditable.class))
{
auditLoggerService.logDelete(entity, id);
}
super.onDelete(entity, id, state, propertyNames, types);
}}
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego
29Projektowanie warstwy serwera Interceptor (III)
<bean id="audytInterceptor"
class="commons.interceptor.AudytInterceptor">
<property name="auditLoggerService" ref="auditLoggerService"></property>
</bean>