You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vaadin 8项目中如何实现独立于UI的服务器启动时代码执行?

在Vaadin 8中实现服务器启动时加载数据库到内存的方案

嘿,这个需求我之前在Vaadin 8项目里刚好折腾过,其实完全可以沿用你熟悉的Servlet相关机制,甚至还有Vaadin特有的适配方案,我给你详细说两种靠谱的实现方式:

方式一:沿用传统的ServletContextListener(推荐无Vaadin依赖的场景)

Vaadin 8本质还是基于Servlet容器运行的,所以你之前用的ServletContextListener方案完全适用,步骤很简单:

  1. 创建一个实现ServletContextListener的类,把数据库加载逻辑放到contextInitialized方法里,别忘了加上@WebListener注解让容器识别:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class DBPreloadListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // 这里写你的数据库加载逻辑,比如把常用字典、配置数据缓存到内存
        System.out.println("服务器启动中,开始加载数据库数据至内存...");
        // 示例:调用自定义的缓存工具类完成加载
        DataCache.loadCommonDBData();
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 可选:服务器关闭时的资源清理逻辑,比如释放缓存连接、清空内存数据
        DataCache.clearAll();
    }
}

只要你的项目是标准Servlet项目(比如用Tomcat、Jetty),启动时容器会自动触发这个方法,和普通Web项目没有区别,完全不需要改动Vaadin的代码。

方式二:使用Vaadin特有的VaadinServiceInitListener(推荐需要和Vaadin上下文交互的场景)

如果你的加载逻辑需要用到Vaadin的服务上下文(比如要读取Vaadin的配置、和UI服务关联),那用Vaadin提供的VaadinServiceInitListener更合适,有两种写法:

写法1:整合到Vaadin Servlet中

直接在你的Vaadin Servlet类里添加监听器:

import com.vaadin.server.ServiceInitEvent;
import com.vaadin.server.VaadinServiceInitListener;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.VaadinServlet;
import javax.servlet.annotation.WebServlet;

@WebServlet(urlPatterns = "/*", name = "MyAppServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
public class MyAppServlet extends VaadinServlet {
    @Override
    protected void servletInitialized() throws ServletException {
        super.servletInitialized();
        // 添加Vaadin服务初始化监听器
        getService().addServiceInitListener(event -> {
            // 执行数据库加载逻辑
            System.out.println("Vaadin服务初始化中,加载数据库数据至内存...");
            DataCache.loadCommonDBData();
        });
    }
}

写法2:单独创建监听器类

也可以把监听器抽成独立类,同样加上@WebListener注解:

import com.vaadin.server.ServiceInitEvent;
import com.vaadin.server.VaadinServiceInitListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class VaadinDBPreloader implements VaadinServiceInitListener {
    @Override
    public void serviceInit(ServiceInitEvent event) {
        // 这里写加载逻辑
        DataCache.loadCommonDBData();
    }
}

这种方式的好处是,监听器会在Vaadin服务初始化时触发,能直接访问Vaadin的服务实例,适合需要和Vaadin生态交互的场景。

总结

  • 如果只是单纯加载数据库数据到内存,和Vaadin功能无关,方式一足够简单直接;
  • 如果加载逻辑需要依赖Vaadin的服务或上下文,方式二是更贴合Vaadin生态的选择。

内容的提问来源于stack exchange,提问作者Eight Rice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:29:31