Джерси - аннотация @Context для инъекций. Как это работает?

Я смотрел хороший учебник REST с использованием Джерси. На странице есть веб-ресурс, который построен под названием TodoResource, который сам содержит две переменные экземпляра

public class TodoResource {
    @Context
    UriInfo uriInfo;

    @Context
    Request request;

    String id;

    public TodoResource(UriInfo uriInfo, Request request, String id) {
        this.uriInfo = uriInfo;
        this.request = request;
        this.id = id;
    }
}

Мне было интересно, как инициализируются переменные экземпляра UriInfo и Request? Я знаю, что использование аннотации @Context позволяет вводить информацию, но в какой момент это происходит? Будет ли это автоматически обрабатываться Джерси?

Ответ 1

Джерси не изменяет класс, но создает его по каждому запросу от клиента.

После вызывается конструктор класса, поля контекста вставляются.
(Если вы попытаетесь получить доступ к этим полям внутри конструктора, они будут null)

В вашем случае классу не нужен конкретный конструктор, поэтому просто:

public TodoResource () {
    // in most cases the ctor stays empty.
    // don't do much work here, remember: the ctor is invoked at every client request
}

Но внутри методов (представляющих веб-ресурсы), аннотированных с помощью @POST, @GET, ..., у вас будет доступ к полям контекста.

Ответ 2

Я столкнулся с некоторыми интересными результатами с Правила впрыска, вот что я нашел:

public class TodoResource{
  @Context
  UriInfo uriInfo; // Set second
  public TodoResource(@Context UriInfo value){
    uriInfo = value; // Set first (makes sense)
  }
  @Context
  public void setUriInfo(UriInfo value){
    uriInfo = value; // Set third
  }
}

Надеюсь, это поможет.

Ответ 3

Использовать аннотацию метода @PostConstruct:

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Path("foo")
public class AuthResource {
    @Context
    HttpServletRequest request;

    public AuthResource() {
        //request is null
    }

    @PostConstruct
    public void postConstruct() {
        //request is NOT null
    }

    @PreDestroy
    public void preDestroy() {
       //after rest method executing
    }
}