[Java Spring] - 심화
AOP (Aspect Oriented Programming)
- 관점 지향 프로그래밍
-
어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화해 재사용할수 있도록 지원하는 것
Aspect
: 관심사를 모듈화 한 것Target
: 클래스, 메서드 등 Aspect를 적용하는 곳Advice
: 실질적인 부가기능을 담은 구현체JointPoint
: Advice가 적용될 수 있는 모든 위치로 추상적 개념PointCut
: JointPoint중 Advice가 적용될 위치를 선별
JDK Dynamic Proxy
- JDK의
java.lang.reflect
패키지에서 제공하는 동적 프록시 기술 - 인터페이스를 구현한 클래스를 동적으로 생성하여 프록시 객체를 생성하는 방법 (타깃의 인터페이스 기준)
- 프록시 객체는 실제 객체를 대신하여 클라이언트 요청을 처리하고, 필요에 따라 추가적인 로직을 수행할 수 있음
특징
- 인터페이스를 구현한 클래스만 프록시 객체를 생성할 수 있음
- 동적으로 생성되기 때문에 프록시 객체의 클래스 파일이 생성되고, 메모리에서 로딩되는 과정이 필요함
- 메소드 호출 시 프록시 객체는
InvocationHandler
를 호출하고,InvocationHandler
는 실제 객체의 메소드를 호출하여 처리함
활용
- AOP(Aspect Oriented Programming) 구현에 많이 사용
- 실제 객체의 동작 이전 및 이후에 공통적인 로직을 구현할 때 유용하다
단점
- 인터페이스를 구현한 클래스만 대상으로 하기 때문에, 인터페이스가 없는 클래스나 메소드에는 적용할 수 없음
- 동적으로 생성된 클래스이기 때문에 디버깅이 어렵고, 성능에도 영향을 미칠 수 있음
- 생성된 프록시 객체는 한 번에 하나의 인터페이스만 구현할 수 있음
CGLIB (Code Generation Library)
- 자바 바이트코드를 사용하여 런타임 시에 클래스를 동적으로 생성하는 라이브러리
- 객체 지향 프로그래밍에서 AOP 구현에 많이 사용됨
특징
- Dynamic Proxy와 비슷한 방식으로 클래스의 메소드를 호출하고, 필드에 접근할 수 있음
- 상속을 통해 클래스를 생성하므로 인터페이스와 클래스 모두를 대상으로 적용 가능함
- 프록시 객체를 생성할 때, 원본 객체를 상속받은 클래스를 생성하여 프록시 객체를 생성함
- 생성된 프록시 객체는 원본 객체의 메소드를 재정의하고, 필요에 따라 추가적인 로직을 수행할 수 있음
활용
- Java Spring은 CGLIB를 활용하여 프록시 객체를 생성하고, AOP 구현에 사용함
- 스프링 빈(Bean)에 대한 메소드 호출 시, 빈의 메소드를 실행하는 대신 CGLIB를 사용하여 프록시 객체의 메소드를 호출함
- 프록시 객체는 메소드 호출 전/후에 공통 로직(예: 로깅, 보안 등)을 수행할 수 있음
한계
- 클래스를 상속받아야 하므로, final 클래스와 메소드에는 적용할 수 없음
default
생성자가 필요하다. (Spring 3.2 이상에서는 해결되었다.)
interceptor
- 컨트롤러에 들어오거나 나가는 요청과 응답을 가로채는 역할
- 컨트롤러 호출 전후에 추가적인 로직 수행 및 반환된 결과 가공
활용
- 컨트롤러 요청 전/후에 공통 로직을 처리하고, 요청 파라미터를 검증하는 등의 기능을 제공
HandlerInterceptor
인터페이스를 구현하여 사용할 수 있으며,preHandle()
,postHandle()
,afterCompletion()
메소드를 오버라이딩하여 컨트롤러 요청 전/후에 처리할 로직을 구현- 필터(Filter)와 비슷한 역할을 하지만, 컨트롤러의 메소드를 직접 호출하여 처리하므로, 컨트롤러의 상태나 뷰(View)에 직접적으로 영향을 미칠 수 있음
장단점
- 컨트롤러 로직을 분리하여 유지보수성을 높이고, 공통 로직을 한 곳에서 관리할 수 있음
- 많이 사용하면 로직의 복잡도가 증가할 수 있으며, 컨트롤러와 인터셉터 간의 상호작용을 고려해야 함
filter와 차이점
- Interceptor는 컨트롤러의 메소드를 직접 호출하여 처리하므로, 컨트롤러와 뷰(View)에 직접적으로 영향을 미칠 수 있음
- Filter는 요청과 응답의 헤더 정보만을 처리하기 때문에, 컨트롤러와 뷰(View)에 영향을 미치지 않음
- Interceptor는 Filter와 달리 DispatcherServlet에서 호출되며, HandlerMapping 정보를 참조할 수 있음
Spring 전체 동작과정
- 클라이언트에서 요청이 발생
- 요청을 DispatcherServlet이 받아들임
- DispatcherServlet은 HandlerMapping을 통해 요청을 처리할 컨트롤러를 찾음
- HandlerAdapter가 컨트롤러를 실행하고, 결과를 ModelAndView 객체로 반환
- ModelAndView 객체가 ViewResolver를 통해 실제 View 객체로 변환
- 변환된 View 객체가 클라이언트에게 응답으로 전송
Leave a comment