RestInterceptor 가 뭐지? -> https://dev-allday.tistory.com/90
기존에 아쉬웠던 점들과 사용성을 개선해 1.0 버전을 릴리즈했다.
UML
가장 큰 변화 - build()
가장 큰 변화는 RestInterceptorRegistry를 통해 RestInterceptor를 등록할 때 반드시 호출해야 했던 build() 메서드가 사라졌다는 것이다.
기존에 RestInterceptorRegistry는 RestInterceptorRegistry 리스트를 필드로 가지고 있다가 build() 메서드가 호출되어야만 RestInterceptor의 설정들을 실제 InterceptorRegistry로 반영했다.
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
private final RestTestInterceptor testInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// Create RestInterceptorRegistry from InterceptorRegistry
RestInterceptorRegistry restInterceptorRegistry = new RestInterceptorRegistry(registry);
restInterceptorRegistry.addInterceptor(testInterceptor)
.addRestfulPatterns(RestfulPattern.of("/memos", HttpMethod.GET)); // GET /memos
restInterceptorRegistry.build(); // 명시적으로 build() 를 호출해야 했음.
}
}
public class RestInterceptorRegistry {
private final InterceptorRegistry registry;
private final List<RestInterceptorRegistration> registrations = new ArrayList<>();
public RestInterceptorRegistry(InterceptorRegistry registry) {
this.registry = registry;
}
public RestInterceptorRegistration addInterceptor(RestInterceptor restInterceptor) {
RestInterceptorRegistration registration = new RestInterceptorRegistration(restInterceptor);
registrations.add(registration);
return registration;
}
public void build() {
this.registrations.forEach(registration -> {
RestInterceptor restInterceptor = registration.getRestInterceptor();
registry.addInterceptor(restInterceptor)
.addPathPatterns(restInterceptor.restfulPatterns.stream()
.map(RestfulPattern::getPath)
.collect(Collectors.toList()))
.order(registration.getOrder());
});
}
}
때문에 사용자는 명시적으로 build() 메서드를 호출해야 했고, 프로그래밍 관점에서 절대 좋은 코드가 아니었다.
이를 해결하기 위해 RestInterceptorRegistration을 InterceptorRegistration과 RestInterceptor의 Adaptor로 디자인했다.
HandlerInterceptor를 등록하는 역할을 하는 Spring의 InterceptorRegistration 은 Path를 기반으로 HandlerInterceptor를 등록한다. 하지만, RestInterceptor는 Path 가 아닌 RestfulPattern을 기반으로 동작한다.
RestInterceptor
public abstract class RestInterceptor implements HandlerInterceptor {
protected List<RestfulPattern> restfulPatterns = List.of();
@Override
public final boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (isPreFlightRequest(request) || shouldSkip(request)) {
return true;
}
return doInternal(request, response, handler);
}
// ....
}
RestfulPattern을 add 하면 RestInterceptor의 restfulPatterns에 추가함과 동시에 InterceptorRegistration의 addPathPatterns() 메서드에 해당 RestfulPattern의 Path를 등록하도록 구현했다.
public class RestInterceptorRegistration {
private final RestInterceptor restInterceptor;
private final InterceptorRegistration registration;
RestInterceptorRegistration(RestInterceptor restInterceptor, InterceptorRegistry registry) {
this.restInterceptor = restInterceptor;
this.registration = registry.addInterceptor(restInterceptor);
}
public RestInterceptorRegistration addRestfulPatterns(RestfulPattern... restfulPatterns) {
return addRestfulPatterns(Arrays.asList(restfulPatterns));
}
public RestInterceptorRegistration addRestfulPatterns(Collection<RestfulPattern> restfulPatterns) {
restInterceptor.restfulPatterns = new ArrayList<>(restfulPatterns);
registration.addPathPatterns(restfulPatterns.stream()
.map(RestfulPattern::getPath)
.toList()
);
return this;
}
public RestInterceptorRegistration order(int order) {
registration.order(order);
return this;
}
}
이를 통해 서로 호환되지 않던 InterceptorRegistration과 RestInterceptor를 연결할 수 있었다.
1.0 버전부터는 불필요한 build() 메서드를 사용할 필요가 없다.
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
private final RestTestInterceptor testInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// Create RestInterceptorRegistry from InterceptorRegistry
RestInterceptorRegistry restInterceptorRegistry = new RestInterceptorRegistry(registry);
restInterceptorRegistry.addInterceptor(testInterceptor)
.addRestfulPatterns(RestfulPattern.of("/memos", HttpMethod.GET)); // GET /memos
}
}
Repository
'Spring Boot' 카테고리의 다른 글
RestInterceptor 개발기 - 패턴 매칭 이슈 (1) | 2024.12.02 |
---|---|
Spring 라이브러리 개발기 - RestInterceptor v0.1 (0) | 2024.11.29 |
Redis 캐싱만 적용하면 끝일까? - Resilience4j 를 통한 Circuit Breaker 적용 (7) | 2024.10.15 |
Spring Boot에서 Redis를 활용해 데이터 캐싱하기(feat. Look Aside) (1) | 2024.06.17 |
Interceptor를 활용한 JWT 토큰 검증 (1) | 2024.06.07 |