假设我已将日志服务部署到某个(符合 jaxrs 的)容器。
@Path("/logger")
public class LogService
{
@GET
@Path("/log")
public Response log(final String @QueryParam("msg") msg)
{
System.out.println(msg);
// ...
}
}
如果我向托管此服务的容器发出以下请求,我希望在容器的标准输出日志中看到我的消息输出:
GET <host>:<port>/logger/log?msg=foo
现在我想用一些任意客户端指定的行为在运行时更改此日志消息的实现。
例如,假设我们有一个接口:
public interface LoggerApi
{
void logMessage(final String msg);
}
并且该服务被重新定义为使用此接口的实现:
@Path("/logger")
public class LogService
{
public static LoggerApi LOGGER = new LoggerApi()
{
void logMessage(final String msg)
{
System.out.println(msg);
}
}
@GET
@Path("/log")
public Response log(final String @QueryParam("msg") msg)
{
LOGGER.logMessage(msg);
// ...
}
}
因此问题就变成了,如何将记录器的实现与服务器外部的某个客户端定义的新实现进行热交换。
我的第一直觉是 RMI 和/或动态代理可以让我到达我想去的地方,但我不确定所有的安全策略疯狂。
基本上我想要的是能够执行以下操作:
@Path("/config")
public class ConfigService
{
@POST
@Path("/loggerApi")
public Response setLoggerApi(final LoggerApi clientSuppliedLogger)
{
LogService.LOGGER = clientSuppliedLogger;
// ...
}
}
想法?
(哦,我知道这会带来严重的安全风险,并且这种模式不应该在生产环境中使用。我的兴趣是设计一个模拟服务,其中服务的行为和副作用可以通过调用模拟服务的集成测试来定义)