[ AOP ] AOP(Aspect-Oriented Programming)의 개념과 인터셉터의 기본 설정 등록 과정 구현

2024. 3. 21. 22:18[ Self-Study ]

환경 : Spring Tool Suite4

 

 

[ AOP(Aspect Oriented Programming) ]

  • Object Oritented Programming의 진화형태
  • 객체를 단순히 만드는 것을 넘어 체계적인 관리를 추구
  • 주어진 컨셉에 맞는 객체를 선별해서 특별한 처리를 추가
  •          └ 주어진 컨셉을 관점(Aspect)이라고 부른다
             └ 특별한 처리를 간섭(Advice)이라고 부른다
  • 스프링에서는 간섭 객체를 직접 만들 수도, 만들어진걸 사용할 수도 있다
                                                                              - 만들어진 간섭 개체는 다음과 같다 
                                                                                    └ 인터셉터(Interceptor)
                                                                                    └ 컨트롤러 어드바이스(Controller Advice)
  • 접근 제한에 대해서 
       간섭 O → 행동의 변화
       간섭 X → 원래대로 
       이게 자유자재로 돼야 함

 

 조금 더 풀어서 설명하자면..

 

 'Aspect'는 프로그램에서 특정 관심사기능을 말한다. 예를 들어, 로깅(무언가가 언제 일어났는지 기록하는 것)이나 보안, 에러처리 같은 것이라고 볼 수 있고, 이런 관심사들은 프로그램 전체에 걸쳐서 나타날 수 있다.

AOP를 사용하면, 이런 관심사들을 각각의 모듈로 분리해서 코드를 짤 수 있다. 이렇게 하면 프로그램이 더 깔끔해지고, 유지보수도 쉬워지기 때문에 AOP를 사용한다. 예를 들어, 프로그램의 여러 부분에서 발생하는 에러를 한 곳에서 처리하거나, 여러 곳에서 사용되는 기능을 한 번에 수정할 수 있게 된다.


 AOP에서 가장 중요한 개념은 'Aspect'이다. Aspect는 특정 관심사에 대한 모듈 또는 코드 덩어리를 말한다. AOP를 사용하면 핵심 비즈니스 로직과 횡단 관심사를 분리할 수 있어. 이것은 주로 'Weaving'이라고 불리는 프로세스를 통해 이뤄져. Weaving은 Aspect를 실제 코드에 삽입하는 과정을 의미해.

AOP의 주요 용어들을 간단히 설명하면:

1. Aspect(관심 모듈): 특정 관심사에 대한 코드를 모은 모듈
2. Advice(조언): Aspect에서 실제로 해야 할 일을 정의하는 부분. 프로그램의 어느 지점에서 어떤 동작을 해야 할지를 명시.
3. Join Point(결합 지점): Advice가 실행될 수 있는 특정 지점. 메소드 호출, 예외 발생 등이 Join Points의 예시.
4. Pointcut(지점 컷): Join Point 중에서 실제로 Advice가 실행될 지점을 선택하는 표현식. 특정 메소드 호출 또는 예외 발생과 같은 특정 조건을 지정할 수 있음.
5. Weaving(위빙): Aspect의 코드를 실제 프로그램 코드에 삽입하는 프로세스를 의미.


[ preHandle ]

 

 `preHandle`은 Spring Framework에서 사용되는 인터셉터(Interceptor) 중 하나에서 사용되는 메서드 중 하나로, 주로 Spring MVC에서 HTTP 요청이 컨트롤러에 도달하기 전에 실행되는 메서드이다.

 Spring MVC는 클라이언트의 HTTP 요청이 서버에 도달할 때, 그 요청을 처리하기 위해 여러 단계의 과정을 거치게 된다. `preHandle` 메서드는 이 과정 중에서 가장 먼저 실행되는 단계 중 하나인 "HandlerInterceptor"에서 사용된다.

 간단히 말하면, `preHandle` 메서드는 컨트롤러가 실행되기 전에 호출되며, 주로 요청에 대한 사전 처리 로직을 수행하는 데 사용된다. 이 메서드를 통해 특정 조건을 확인하거나 요청을 가로채는 등의 작업을 수행할 수 있습니다. 이를 통해 예를 들면, 로그인 여부 체크, 권한 확인 등을 할 수 있어요.

예를 들어, 다음은 간단한 `HandlerInterceptor` 클래스의 예시입니다:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 컨트롤러 실행 전에 수행할 로직
        // 예: 로그인 여부 체크, 권한 확인 등

        return true; // true를 반환하면 계속 진행, false를 반환하면 중단
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        // 컨트롤러가 실행된 후, 뷰가 렌더링되기 전에 수행할 로직
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // 뷰가 렌더링된 후에 수행할 로직
    }
}



이렇게 만들어진 인터셉터를 설정 파일에서 등록하면, `preHandle` 메서드가 컨트롤러 실행 전에 호출되어 추가적인 로직을 수행할 수 있게 됩니다.

 


- TestInterceptor.java

//특정 주소(URL)에 대한 처리 과정을 간섭할 수 있는 객체
//인터셉터는 특별한 처리를 수행하기 때문에 만드는 방법이 정해져 있다
// [1] 상속을 통해 자격요건을 획득한다 (HandlerInterceptor)
// [2] 스프링에 등록한다
// [3] 간섭 메소드를 재정의하여 내용을 작성한다

/* - preHandle 메소드는 컨트롤러가 실행되기 전 시점을 간섭할 수 있다 
 *		└ true를 반환하면 통과, false를 반환하면 차단 */
@Service
public class TestInterceptor implements HandlerInterceptor{

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("인터셉터 실행");
		return true; //통과(어어 그래 지나가)
	}
	
}

    (+) 스프링 콘솔창에 인터셉터 실행 문구가 출력 됨

 

- InterceptorConfiguration.java

//application.properties에서 하기 힘든 설정들을 이곳에서 구현할 수 있다
// [1] 상속을 통한 자격 획득 (WebMvcConfigurer)
// [2] 등록
// [3] 필요한 메소드를 재정의하여 설정 구현
@Configuration
public class InterceptorConfiguration implements WebMvcConfigurer{
	
	@Autowired
	private TestInterceptor testInterceptor;
	
	@Autowired
	private MemberInterceptor memberInterceptor;
	
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		//registry에다가 인터셉터 주소와 함께 등록
		//registry.addInterceptor(인터셉터객체).addPathPatterns(주소);
		registry.addInterceptor(testInterceptor).addPathPatterns("/**"); // "/**" 전체 주소
//		registry.addInterceptor(testInterceptor).addPathPatterns("/pocketmon/list", "/emp/list");
		
		
	}
	
}

 

 

 

 

 

개인 공부 기록용입니다:)

Chat GPT와 함

728x90