개발/java

actuator사용시 Swagger 3.0과 충돌하는 현상 해결법

코딩하는꽃개 2023. 5. 3. 22:36
반응형
 

현상

Spring Boot 2.6.x 이상 버전에서 swagger 를 사용하고자 할 시 "failed to start bean 'documentationpluginsbootstrapper'; nested exception is java.lang.nullpointerexception" 에러가 발생하며 스프링 부트 기동이 불가능한 현상이 발생함.

 

 

원인

Springfox는 Spring MVC가 경로를 찾게 하기 위하여 Ant-based Path Macther를 사용하도록 하고 있습니다.

2.6.x 이상의 버전부터 해당 matcher를 Path Pattern-based Macther로 변경하여 필요한 클래스를 찾지 못하게 되어 발생하는 현상 입니다.

인터넷을 찾아보면 아래의 코드를 application.yml에 추가하여 해결할 수 있다고 나와있다.

spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

 

하지만 프로젝트가 Actuor를 사용하고 있는 경우는 위 설정을 추가해도 정상적으로 작동하지 않습니다. 

Swagger가 endpoint에 대해서 문서화를 해주는데 이 과정에서 Actuor의 endpoint 관련 클래스와 충돌이 발생한 것으로 보입니다.

 

 

해결

아래의 빈을 등록해 주면 정상적으로 작동할 수 있습니다.

 

/**
 * Swagger 의존성 문제 해결을 위한 빈 등록
 */
@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
    return new BeanPostProcessor() {

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
                customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
            }
            return bean;
        }

        private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
            List<T> copy = mappings.stream()
                .filter(mapping -> mapping.getPatternParser() == null)
                .collect(Collectors.toList());
            mappings.clear();
            mappings.addAll(copy);
        }

        @SuppressWarnings("unchecked")
        private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
            try {
                Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
                field.setAccessible(true);
                return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
            } catch (IllegalArgumentException | IllegalAccessException e) {
                throw new IllegalStateException(e);
            }
        }
    };

 

주의할 점은 RequestMappingInfoHadlerMapping 패키지는org.springframework.web.servlet.mvc.method 내에 있는 메서드를 임포트해야 합니다.

import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
반응형