我需要一个简单的api代理来为我的spring启动应用程序创建基于来自数据库的值的代理Map。我找到了这个api代理https://github.com/mitre/http-proxy-servlet 这很简单,也符合我的目的
我发现创建动态代理servlet的唯一方法如下所示。
@ManagedBean
public final class ExecutorListener implements ServletContextInitializer {
private static final String TARGET_URI = "targetUri";
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
EndpointsRepo endpointrepo = springContext.autowireBean(EndpointsRepo.class);
List<Endpoint> endpoints = endpointrepo.findAll();
for(Endpoint endpoint: endpoints){
ServletRegistration.Dynamic dispatcher = servletContext.addServlet(endpoint.getEndpointCode(), new ProxyServlet());
dispatcher.setLoadOnStartup(1);
dispatcher.setInitParameter(TARGET_URI, endpoint.getEndpointUrl());
dispatcher.addMapping(endpoint.getUrlPattern());
}
}
代理现在可以正常工作,除非我更新db中的Map值,我需要这些值反映在动态代理中。
有没有办法在不重新启动spring引导应用程序的情况下刷新servletMap?我尝试使用applicationcontext.refresh(),但它是由db datasource发出无法关闭的消息并导致内存泄漏引起的。
如果我尝试在运行时使用springservletregistration添加bean,那么创建的Map将不起作用。似乎只有在启动之前配置servlet,servletMap才能工作,正如springservlet文档所说的那样。
1条答案
按热度按时间s4chpxco1#
您不能在初始化阶段之后添加其他servlet,因为servlet api规范(参见Javaservlet规范,版本4.0)禁止这样做。在第4.4节中
ServletContext#addServlet
方法是:这些方法只能在应用程序初始化期间从
contexInitialized
a方法ServletContextListener
执行或从onStartup
a方法ServletContainerInitializer
实施。你仍然可以重复使用
ProxyServlet
类,但您需要编写自己的servlet(Map到/*
),这将创建ProxyServlet
,配置它们并将请求路由到正确的请求。编辑:基本上你需要这样一个类:
完整的代码在要点上。