Wyklad9(SpringAOP)

Download Report

Transcript Wyklad9(SpringAOP)

Projektowanie warstwy serwera
Programowanie
aspektowe
Projektowanie warstwy serwera
2
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
AOP - przykłady zastosowania
–
–
–
–
–
Projektowanie warstwy serwera
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
3
AOP – podstawowe pojęcia (I)
Projektowanie warstwy serwera
• 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
4
AOP – podstawowe pojęcia (II)
Projektowanie warstwy serwera
Projekt współfinansowany przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
5
Projektowanie 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
6
Projektowanie 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
7
Projektowanie 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
8
Projektowanie 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
9
Projektowanie 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
10
Projektowanie 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
11
Projektowanie 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
12
Projektowanie 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
13
Projektowanie warstwy serwera
14
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
Przykład
Projektowanie warstwy serwera
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
15
Projektowanie warstwy serwera
@Aspect
@Aspect
public class MyAspect
{
.....
}
Projekt współfinansowany przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
16
Projektowanie warstwy serwera
@Pointcut
@Pointcut("execution(* transfer(..))")
private void my()
{}
• execution
• target
• args
Projekt współfinansowany przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
17
Projektowanie 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
18
Projektowanie warstwy serwera
Stosowane adnotacje
•
•
•
•
•
@Before()
@AfterReturning(Object)
@AfterThrowing(Exception)
@After()
@Around(ProceedingJoinPoint)
Projekt współfinansowany przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
19
Projektowanie 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
20
Przykład
Projektowanie warstwy serwera
@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
21
Projektowanie warstwy serwera
Konfiguracja
<aop:aspectj-autoproxy/>
<bean class=”common.DataUpdateInterceptor ">
</bean>
Projekt współfinansowany przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
22
Projektowanie warstwy serwera
@Auditable
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Auditable
{
}
Projekt współfinansowany przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
23
Projektowanie warstwy serwera
@NonAuditableField
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NonAuditableField
{
}
Projekt współfinansowany przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
24
Projektowanie 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
25
Projektowanie 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
26
Projektowanie 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
27
Projektowanie 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
28
Projektowanie warstwy serwera
Interceptor (III)
<bean id="audytInterceptor"
class="commons.interceptor.AudytInterceptor">
<property name="auditLoggerService"
ref="auditLoggerService"></property>
</bean>
Projekt współfinansowany przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
29