如何在Spring Boot+Tomcat环境下注册可被多个WAR包共享的Bean
实现Tomcat多WAR应用共享Spring Bean的方案
步骤1:将共享类放到Tomcat公共类路径
Tomcat的每个Web应用都有独立的类加载器,默认类加载隔离,因此要共享的类必须放在所有应用都能访问的公共类路径下:
将TestData类编译后打包为独立的jar包,放到%TOMCAT_HOME%/lib目录下。后续每个WAR应用依赖这个jar时,将依赖的scope设置为provided,避免重复打包到WAR的WEB-INF/lib中导致类加载冲突。
步骤2:Tomcat启动时初始化共享Bean并注册到全局上下文
通过Tomcat全局的ServletContext监听器实现启动时初始化共享实例,监听器同样打包到刚才的公共jar中,放到Tomcat的lib目录下。
监听器代码示例
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class SharedBeanInitListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { // 初始化共享Bean,可在此处加载配置、赋值等 TestData sharedTestData = new TestData(); sharedTestData.setUsername("全局共享用户名"); // 将实例存入全局ServletContext sce.getServletContext().setAttribute("sharedTestData", sharedTestData); } @Override public void contextDestroyed(ServletContextEvent sce) { // 按需添加销毁逻辑 } }
注册全局监听器
修改Tomcat全局配置文件%TOMCAT_HOME%/conf/web.xml,添加监听器注册:
<listener> <listener-class>你的包路径.SharedBeanInitListener</listener-class> </listener>
步骤3:每个Spring Boot应用读取共享实例注册为本地Bean
在每个WAR应用中添加配置类,从全局ServletContext中读取共享实例,注册到当前应用的Spring容器中,即可直接通过@Autowired注入使用,无需修改原有业务代码。
配置类代码示例
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.WebApplicationContext; @Configuration public class SharedBeanConfig { @Bean public TestData testData(WebApplicationContext context) { return (TestData) context.getServletContext().getAttribute("sharedTestData"); } }
注意事项
- 如果需要多应用修改共享Bean的属性时保证线程安全,需要给
TestData的属性读写方法加锁,或者使用原子类包装属性。 - 严格保证所有应用依赖的
TestData类都是从Tomcat公共lib加载,避免出现类转换异常。
内容的提问来源于stack exchange,提问作者sksm216
相关产品推荐
相关产品推荐

