관점 지향 프로그래밍 - 사용자 중심인 객체 지향 프로그래밍에서 좀 더 큰 틀인 관점 지향 프로그래밍이라고 합니다. - 기존엔 사용자가 원하는 업무 기반의 로직에만 관심을 가졌었지만, 사용자의 요구사항말고 이 요구사항을 수반하기 위해 코드들을 작성하다보니 그 외의 코드가 들어가게 됨을 느낍니다.
(개발자/관리자가 프로그램을 구현하기 위해서든 테스트하기 위해서든 필요한 코드들이 존재하게 됨.)
- 사용자 관점으로 봤떤것이 지금까지 객체지향으로 잘 만들어 졌다면, 추가로 만들게 되는 로직을 개발자/운영자 관점에서 넣어야하는 로직이 있어야함. - 이걸 관점 지향 업무라 함. (객체지향보다 큰 개념) - 주 업무 로직 : 객체지향, 그 외의 것까지 포함 : 관점 지향
- Primary(Core) Concern : 관점에 해당되는 것중에서 주 관심사에 해당되는 것들은 객체로 만들어짐, 실질적인 업무들은 메소드로 만들어짐
- cross-cutting : 관점이 다른로직 - 주업무 로직과 뺏다 꽂았다가 자유로워야 함. - 보안처리 : 권한을 줄수도 뺄수도있어야함. - 로그처리 : 남겼다 뺏다 지웠다.. - 과거 커팅작업이 쉽지않아 직접 지우거나,, 주석처리,,, 소스를 가지고 잇는 사람만이 할 수 있고 재배포에 불편함을 느꼈습니다.
그래서 이 방법을 쉽게 해보려고 생각해낸게 AOP 방법론이라고 합니다.
그림 출처.... 구글링...... 주소를 잃어버렸씁니다.
- 주 업무 로직 분리(Core Concern) , 개발자가 처리 방식을 따로 생성 (cross cutting Concern)
프록시 개념 - 실제 주 업무를 갖고 있는 녀석을 호출해주는 그러한 역할을 함. - 사용자는 주업무로직을 직접 호출하는게 아니라 프록시를 호출하게 됨. - 프록시에서 앞뒤로 개발자가 원하는 코드를 삽입
스프링 방식의 AOP
- 스프링을 이용하면 이것을 자유롭게 구현이 가능함. - 파일 구성
Program.java
public class Program {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring/aop/setting.xml");
// ApplicationContext context = new AnnotationConfigApplicationContext(NewlecAppConfig.class);
Exam exam = context.getBean("exam",Exam.class);
System.out.printf("total is %d\n", exam.total());
System.out.printf("avg is %f\n", exam.avg());
}
}
LogAroundAdvice - implements MethodInterceptor (작업 전 후로)
(반환 값을 가지고 할것이 있다면) logAfterReturning 결과값을 반환한다음 이어서 작업할게 있으면 .. - implements AfterReturningAdvice
LogAfterThrowingAdvice - implements ThrowsAdvice 어떤 예외가 발생하느냐에 따라 함수의 인자가 달라짐
LogAroundAdvice
package spring.aop.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
// 주 업무 로직의 앞 뒤로 생성
public class LogAroundAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
long start = System.currentTimeMillis();
Object result = invocation.proceed();
long end = System.currentTimeMillis();
String message = (end - start) + "ms 시간이 걸렸다.";
System.out.println(message);
return result;
}
}
LogBeforeAdvice
package spring.aop.advice;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
// 주 업무 로직의 앞에서만 실행이 됨.
public class LogBeforeAdvice implements MethodBeforeAdvice{
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("앞에서 실행될 로직");
}
}
LogAfterReturningAdvice
package spring.aop.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
// 주 업무 로직의 결과값을 이용하여 ..
public class LogAfterReturningAdvice implements AfterReturningAdvice{
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
// TODO Auto-generated method stub
System.out.println("returnValue:"+returnValue + ", method:"+method.getName());
}
}
LogAfterThrowingAdvice
package spring.aop.advice;
import org.springframework.aop.ThrowsAdvice;
// 예외가 발생했을 시.
public class LogAfterThrowingAdvice implements ThrowsAdvice{
public void afterThrowing(IllegalArgumentException e) throws Throwable{
System.out.println("예외가 발생하였습니다.: " + e.getMessage());
}
}
- Spring AOP 용어
AOP는 프록시를 갖고있음 - 포인트 컷(Pointcuts) : total() 메서드만 위빙이 됐음 좋겠다. (별도의 메서드만 호출) - 조인 포인트(JoinPoint) : 프록시는 타겟을 대상으로 모든 메서드를 조인포인트라 생각함.조인하게될 메서드 포인트 - 위빙(weaving) : 프록시와의 연결과정
org.springframework.aop.support.NameMatchMethodPointcut -네임이란것을 기준으로 하는 포인트 컷 - total, avg : advice 별로 포인트 컷 사용 가능
org.springframework.aop.support.DefaultPointcutAdvisor - 포인트 컷과 어드바이스를 연결해주는 역할