Итак, я пытаюсь выполнить бенчмаркинг на Spring MVC (в основном только с контроллерами REST) без контейнера; просто Spring и обработка запроса. С Джерси я могу сделать что-то вроде этого:Испытание Spring MVC через JMH
private volatile ApplicationHandler handler;
private volatile ContainerRequest request;
@Setup
public void start() throws Exception {
handler = new ApplicationHandler(new JerseyAppConfig());
request = ContainerRequestBuilder
.from("/hello?test=HelloWorld", "GET")
.build();
}
@Setup(Level.Iteration)
public void request() {
request = ContainerRequestBuilder
.from("/hello?test=HelloWorld", "GET")
.build();
}
@Benchmark
public Future<ContainerResponse> measure() throws Exception {
return handler.apply(request);
}
ApplicationHandler
является основной точкой входа в процессе обработки запроса Джерси. Вся моя конфигурация Джерси находится в JerseyConfig
. В основном все, что происходит, это то, что я создаю запрос (ContainerRequest
), а затем обрабатывать запрос - это просто вопрос вызова обработчика, передающего запрос. После того как запрос проходит цикл обработки запроса, возвращается ответ.
Я пытаюсь имитировать эту же функциональность с помощью Spring MVC. На самом деле я понятия не имел, как я буду заниматься этим. Я только начал бросать вещи на стену, надеясь, что это будет. У меня возникла идея, что, возможно, я смогу сделать это с помощью DispatcherServlet
(или, точнее, FrameworkSevlet
). Но чтобы сделать это, единственный способ, который я мог видеть, - сделать защищенный processRequest
доступным через отражение. Вот моя попытка
private volatile AnnotationConfigWebApplicationContext appContext;
private volatile FrameworkServlet dispatcherServlet;
private volatile HttpServletRequest request;
private volatile HttpServletResponse response;
private volatile Method processRequest;
@Setup
public void start() throws Exception {
appContext = new AnnotationConfigWebApplicationContext();
appContext.register(SpringAppConfig.class);
dispatcherServlet = new DispatcherServlet(appContext);
processRequest = dispatcherServlet.getClass().getSuperclass()
.getDeclaredMethod("processRequest",
HttpServletRequest.class,
HttpServletResponse.class);
processRequest.setAccessible(true);
}
@Setup(Level.Iteration)
public void request() throws Exception {
request = new MockHttpServletRequest("GET", "/hello");
response = new MockHttpServletResponse();
}
@Benchmark
public void measure() throws Exception {
processRequest.invoke(dispatcherServlet, request, response);
}
Это не работает. Я получаю NPE в this line, который, как я предполагаю, означает, что webApplicationContext
имеет значение null. Но я устанавливаю его выше.
NPE или нет, я даже не уверен, что я собираюсь сделать это правильно; если есть какой-то другой компонент, который я должен искать, а не DispatcherServlet
.
У кого-нибудь есть идеи, как это сделать? Должен ли я искать другой компонент, вызывая другой метод? Любая конфигурация, которую я могу упустить, чтобы на самом деле сделать мою вышеприведенную попытку?
Требование стоит
- Использование JMH
- Тест пропускной способности только Спринг обработки запроса на ответ.
Посмотреть полную Runnable проекту on GitHub