기존에는 개발자 또는 운영자에게 필요한 기능을 사용자를 위해 작성한 자바 코드에 직접 삽입하여 사용하곤 했다.
public int total() {
long start = System.currentTimeMillis();
int result = kor + eng + math + com; // 사용자 코드 부분(주 업무)
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long end = System.currentTimeMillis();
String message = (end - start) + "ms 시간이 걸렸습니다."; // 개발자 및 운영자 코드 부분(부 업무)
System.out.println(message);
return result;
}
다만 위처럼 할 경우 코드가 복잡해지고 사용자 코드를 직접 열어서 수정해야하는 불편함이 생기게 된다.
따라서 관리자 코드 부분을 따로 작성하는 방식을 채택하였는데 이러한 방식을 AOP(Aspect Oriented Programming)라고 한다. 관점 지향 프로그래밍이라고도 불리며, 관점 지향은 쉽게 말해 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화하겠다는 것이다.
여기서 핵심적인 관점은 사용자 코드(주 업무), 부가적인 관점은 관리자 코드(부 업무)라고 볼 수 있다.
이를 실현하기 위해서는 두 코드를 연결해줄 수 있는 도구가 필요한데 이를 프록시(Proxy)라고 부른다. 프록시는 타겟을 감싸서 타겟의 요청을 대신 받아주는 랩핑(Wrapping) 오브젝트이다.
호출자(클라이언트)에서 타겟을 호출하게 되면 타겟이 아닌 타겟을 감싸고 있는 프록시가 호출되어, 타겟 메소드 실행전에 선처리, 타겟 메소드 실행 후, 후처리를 실행시키도록 구성되어있다.
프록시는 아래 구문을 통해 생성할 수 있다.
Exam proxy = Proxy.newProxyInstance(loader, interfaces, h);
여기서 인자로 들어가는 loader는 프록시가 호출할 업무가 있는 클래스 정보이고, interfaces는 말그대로 loader로 대입된 클래스가 구현하는 인터페이스를 말한다. 다만 보다시피 복수형이기 때문에 배열의 형태로 전달해야 한다. 마지막으로 h는 우리가 실행할 관리자 코드, 즉 부가적인 업무를 말한다.
따라서 h에는 다음과 같이 익명 클래스를 작성할 수 있다.
Exam proxy = (Exam) Proxy.newProxyInstance(NewlecExam.class.getClassLoader(), new Class[] {Exam.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long start = System.currentTimeMillis();
Object result = method.invoke(exam, args);
long end = System.currentTimeMillis();
String message = (end - start) + "ms 시간이 걸렸습니다.";
System.out.println(message);
return result;
}
}
);
여기서 invoke 함수는 주 업무가 끝난 뒤, 모든 데이터를 반환할 수 있도록 반환 값이 Object로 설정되어 있으며 우리는 method.invoke() 함수를 통해 이 값을 받아올 수 있다.
이제 우리가 생성한 프록시를 다음과 같이 사용할 수 있다.
System.out.printf("total is %d\n", proxy.total());
System.out.printf("total is %d\n", proxy.avg());
'🍃 Spring, Spring Boot > 스프링 프레임워크 기초' 카테고리의 다른 글
[Java / Spring] 9. Point Cut(Weaving, Join Point) (0) | 2022.04.17 |
---|---|
[Java / Spring] 8. 스프링으로 AOP 구현해보기 (0) | 2022.04.17 |
[Java / Spring] 6. XML Configuration을 Java Configuration으로 변경하기 (0) | 2022.04.11 |
[Java / Spring] 5. 어노테이션을 이용한 객체 생성 (0) | 2022.04.11 |
[Java / Spring] 4. 어노테이션을 이용할 때의 장점과 @Autowired를 이용한 DI 해보기 (0) | 2022.04.11 |