java—确保在Web服务器在spring引导中公开http之前执行代码

t2a7ltrp  于 2021-06-27  发布在  Java
关注(0)|答案(2)|浏览(242)

在springbootweb应用程序中,是否可以确保在嵌入式web服务器(tomcat)侦听传入请求之前执行一些代码?
我有一些数据库迁移脚本需要在restapi的任何请求被应用程序响应之前运行。我该怎么做?目前,我的迁移脚本组件使用 @EventListener 为了 ContextRefreshedEvent 但那太晚了。之前已经记录了以下行:
o、 s.b.w.embedded.tomcat.tomcatwebserver:tomcat在端口8091(http)上启动,上下文路径为“”

z9gpfhce

z9gpfhce1#

您可以在bean中使用@postconstruct方法连接到数据库(存储库),并在那里编写运行脚本所需的代码,该代码将在创建bean之后但在服务器运行之前执行。
例子:https://www.baeldung.com/spring-postconstruct-predestroy

42fyovps

42fyovps2#

我采用了以下方法:

@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的(基)类型。

相关问题