如何注册可以被多个war (Spring boot + Tomcat)共享的bean



我正在开发一个使用Spring引导的应用程序,并将多个war部署到外部tomcat。我想在tomcat启动时用这些war注册一个可共享的bean。

我使用:Java8, Spring boot(2.5.5)和Tomcat9

我想被应用程序共享:

public class TestData {
private String username;

public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}

SampleApp(有多个应用程序以相同的方式自动调用一个TestData实例):

@SpringBootApplication
@RestController
public class App extends SpringBootServletInitializer {
@Autowired
TestData testData;

public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(App.class);
}
@RequestMapping(value = "SampleApp1", method = RequestMethod.GET)
public String getUsername() {
return testData.getUsername();
}
}

我想你的问题是关于在同一web服务器中部署的不同应用程序容器之间共享一个单例Bean的数据。

出于安全原因,这是不可能的。每个部署的应用程序都有自己的类加载器,因此不能轻易访问驻留在其他容器内存中的bean。

我建议你添加一个可以被不同部署的应用访问的微服务,并使用它。它可以很容易地通过OpenFeign作为客户端访问,如果操作正确,它几乎看起来像一个带有getter和setter的bean。

你的问题有好几种方法,可以在不同的层次上解决。

  1. 创建共享库并将其安装到Tomcat服务器。"Install"通常表示将组装好的jar放到$CATALINA_HOME/lib目录或类似目录下。类装入器HOW-TO可以提供更多细节。不确定它是如何与类的共享实例一起工作的,但是通过共享库共享(例如工厂)和配置是绝对可能的。通过共享配置和工厂,您至少可以生成相同的bean(不一定是相同的,但对于您的情况似乎足够了)。

  2. 定义JNDI资源在所有应用程序之间共享。当然,这需要Tomcat可以访问您的类,因此您必须首先检查选项1。这样你就可以"出版"了。所有应用程序共享的类的instance。详细信息可以在JNDI参考资料HOW-TO中找到。使用这种方法,您可以使用@Resource注释注入已发布的资源。

  3. 创建一个微服务(正如另一个答案所暗示的那样),它可以为您提供数据和功能,并从您的应用程序访问它。这给了你最大的灵活性,但也带来了复杂性,需要实际的通信到微服务。

显然,选项1和2需要直接访问服务器配置。

最新更新