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