AOP : 관점지향프로그래밍 (aspect- oriented programming)
Spring AOP : schema-based approach or @AspectJ
1. AOP Concepts
Aspect : before , after , throws , finally 같은 것들을 관리해준다
Transaction management - 실제 비즈니스 로직에서는 트랜잭션 코드를 숨길 수 있다
Join point : Aspect가 동작해야 될 포인트
Advice : Join 포인트가 언제 동작할건지 관리 (before, after , around)
pointcut : 조인 포인트를 판단하는것 인데 어떻게 포인트 컷을 걸지 포인트컷 하나에 여러개의 조인 포인트가 생길 수 있다
target object : 각각의 aop가 동작되어야 할 타겟
AOP proxy : jdk dynamic proxy or CGLIB proxy 사용
weaving : Aspect와 join point가 동작되는 곳을 왔다 갔다 하는 것을 위빙 , Spring 에서는 runtime에 weaving 한다
Advice 종류 (5개의 Advice 제공)
- before : 특정 조인 포인트 전에 동작하는 Advice
- after(returning) : 조인 포인트가 동작하고나서 문제없을 시 동작하는 Advice
- after(throwing) : 조인 포인트가 동작을 하다가 Exception을 발생시켰을 때 동작하는 Advice
- after : 정상 혹은 에러일 때 둘 다 finally 처럼 동작하는 Advice
- around : 보통 많이 쓰이는데 before, after 등 위의 4가지를 하나로 합쳐놓은 것과 같다.
2. AOP Proxies
JDK dynamic proxies : 인터페이스만 제공 그러므로 구현클래스의 경우 사용 불가
(인터페이스를 이용해서 사용)
CGLIB proxices : 클래스를 이용해서 사용
public class Main {
public static void main(String[] args) throws SQLException {
Pojo pojo = new SimplePojo();
pojo.foo();
ProxyFactory factory = new ProxyFactory(new SimplePojo());
factory.addInterface(Pojo.class);
factory.addAdvice(new RetryAdvice());
Pojo pojo = (Pojo) factory.geAtProxy();
System.out.println(">>>");
pojo.foo();
System.out.println(">>>");
context.close();
}
}
class RetryAdvice implements MethodInterceptor{ //spring에서 제공하는 일종의 AOP
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
//return null; // return null 하면 프록시 사이의 함수가 동작 안한다
System.out.println("before"); //이런식으로 before , after 로직도 구현 가능
Object proceed= methodInvocation.proceed();
System.out.println("after");
return proceed; //이렇게 리턴을 해야 프록시 사이의 함수가 작동
}
}
interface Pojo{
void foo();
}
class SimplePojo implements Pojo{
public void foo(){
System.out.println("run foo");
}
}
Plain Object를 호출하기 전에 프로기로 감싼다
실제 프록시를 통해서 오브젝트를 호출
프록시에 감싸져있던 foo() 실행
3. @Aspectj support
1. Enabling @AspectJ Support
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}
2. Declaring an Aspect
@Aspect
public class NotVeryUsefulAspect {
}
3. Declaring a Pointcut
@Pointcut("execution(* transfer(..))") // the pointcut expression
private void anyOldTransfer() {} // the pointcut signature
4. Declaring Advice
1) Before Advice
@Aspect
public class BeforeExample {
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doAccessCheck() {
// ...
}
}
2) After Returning Advice
@Aspect
public class AfterReturningExample {
@AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doAccessCheck() {
// ...
}
}
3) After Throwing Advice
@Aspect
public class AfterThrowingExample {
@AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doRecoveryActions() {
// ...
}
}
4) After (Finally) Advice
@Aspect
public class AfterFinallyExample {
@After("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doReleaseLock() {
// ...
}
}
5) Around Advice
@Aspect
public class AroundExample {
@Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
※AOP를 사용하면 실제로 비즈니스 코드를 분리할 수 있는 강점이 있다.
'Spring' 카테고리의 다른 글
[Spring] Socket통신과 Http통신의 초간단 설명 (0) | 2020.07.04 |
---|---|
[Spring] WebApplicationInitializer (0) | 2020.06.14 |
[Spring] 예제로 보는 Resources (0) | 2020.05.29 |
[Spring] 예제로 보는 Environment Abstraction (0) | 2020.05.27 |
[Spring] 예제로 보는 Java-based Container Configuration (0) | 2020.05.21 |