>source

스프링 부트 웹 애플리케이션에서 임베디드 웹 서버 (tomcat)가 들어오는 요청을 수신하기 전에 일부 코드가 실행되도록 할 수 있습니까?

REST API의 요청이 애플리케이션에서 응답하기 전에 실행해야하는 데이터베이스 마이그레이션 스크립트가 있습니다. 어떻게 할 수 있습니까? 지금은 마이그레이션 스크립트 구성 요소에서 @EventListener ...에 대한 ContextRefreshedEvent 그러나 그것은 너무 늦었습니다. 다음 줄은 이전에 이미 기록되었습니다.

o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8091 (http) with context path ''


  • 답변 # 1

    데이터베이스 (저장소)에 연결하는 데 사용하는 Bean에서 @PostConstruct 메소드를 사용하고 스크립트를 실행하는 데 필요한 코드를 작성할 수 있습니다.이 코드는 Bean이 생성 된 후 서버가 실행되기 전에 실행됩니다.

    예 : https://www.baeldung.com/spring-postconstruct-predestroy

  • 답변 # 2

    여기에서 적용한 다음 접근 방식을 사용했습니다.

    @Component
    @RequiredBy(WebServerFactory.class) // initialize before web server listens for requests
    public class MigrationLogicApplicationRunner {
        ...
    }
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface RequiredBy {
        Class<?> value();
    }
    @Component
    public class RequiredByBeanDefinitionPostProcessor implements BeanDefinitionRegistryPostProcessor {
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        }
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            for (String beanWithRequiredBy : beanFactory.getBeanNamesForAnnotation(RequiredBy.class)) {
                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanWithRequiredBy);
                try {
                    Class<?> beanClass = Class.forName(beanDefinition.getBeanClassName());
                    if (beanClass.isAnnotationPresent(RequiredBy.class)) {
                        Class<?> dependant = beanClass.getAnnotation(RequiredBy.class).value();
                        for (String otherBeanName : beanFactory.getBeanNamesForType(dependant)) {
                            BeanDefinition otherBeanDefinition = beanFactory.getBeanDefinition(otherBeanName);
                            otherBeanDefinition.setDependsOn(ArrayUtils.add(otherBeanDefinition.getDependsOn(), beanWithRequiredBy));
                        }
                    }
                }
                catch (ClassNotFoundException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
    
    

    자신 @RequiredBy 주석이 처리되고 사후 처리 단계에서 다른 Bean 정의에 "종속"을 추가합니다. 어노테이션 매개 변수는 대상 Bean의 (기본) 유형입니다.

관련 자료

  • 이전 GitHub 작업 및 Docker 작성
  • 다음 r - 목록에있는 모든 dataframe 열의 클래스 가져 오기