Vaadin 8项目中如何实现独立于UI的服务器启动时代码执行?
在Vaadin 8中实现服务器启动时加载数据库到内存的方案
嘿,这个需求我之前在Vaadin 8项目里刚好折腾过,其实完全可以沿用你熟悉的Servlet相关机制,甚至还有Vaadin特有的适配方案,我给你详细说两种靠谱的实现方式:
方式一:沿用传统的ServletContextListener(推荐无Vaadin依赖的场景)
Vaadin 8本质还是基于Servlet容器运行的,所以你之前用的ServletContextListener方案完全适用,步骤很简单:
- 创建一个实现
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
相关产品推荐
相关产品推荐

