Здесь происходит много-много-много вещей. Давайте попробуем разобраться с ними один за другим.
Во-первых, @RequestScoped
- это аннотация, которую вы надеваете на то, что сделано . Это аннотация объема, которая сообщает CDI, как долго должна существовать созданная вещь. Пытаясь сохранить простоту, это может быть Java класс:
@RequestScoped
public class Frobnicator { /* ... */ }
… или это может быть метод производителя:
@Produces
@RequestScoped
Frobnicator makeRequestScopedFrobnicator() { /* ... */ }
(Вы можете поместите его в поле, но в этом исключительно редком случае ваше поле теперь действует как сам производитель . Вы можете прочитать о полях производителя , но за исключением некоторых Java EE Scenar ios они почти всегда неверный подход. В вашем случае, как указано выше, это безусловно неправильный подход.)
Положить @Inject
и @RequestScoped
ни в чем не имеет никакого смысла.
Так что ответ на ваш первый вопрос: нет.
Ваш второй вопрос также может быть отклонен на перевале, потому что вы никогда не используйте аннотации области видимости (например, @RequestScoped
) в сценарии внедрения ios. Вы всегда используете их в производственном сценарии ios.
Другими словами, когда вы @Inject
что-то, по определению вы в основном не знаете, в каком объеме находится вещь, которую вы только что ввели; вы просто используете его как обычный POJO, а CDI позаботится о том, чтобы дать вам правильную вещь.
Итак, в вашем случае это выглядит так, как будто вы хотите это:
@Path("hello")
public class HelloResource {
@Inject
FirstService service1;
@Inject
SecondService service2;
/* etc. */
}
… и:
// We'll talk about the lack of annotations here in a moment
public class FirstService {
private static final Logger LOGGER = ...
@Inject
HttpServletRequest request;
/* etc. */
}
Это хорошо, насколько это возможно, но какой объем имеет FirstService
? И знает ли CDI об этом вообще?
Быстрые ответы на на этот вопрос , соответственно: @Dependent
(поскольку на нем нет других аннотаций области видимости) и "вероятно, нет". Это почти наверняка не то, что вы хотите.
Чтобы копнуть немного дальше, теперь вам нужно взглянуть на ваш META-INF/beans.xml
в архивном корпусе FirstService
. Если он указывает, что его bean-discovery-mode
равен annotated
, что весьма вероятно, то только классы с аннотациями, определяющими компонент на них, будут обнаружены КДИ. Так как FirstService
не имеет каких-либо аннотаций, скорее всего, он не будет обнаружен, и CDI взорвется когда-нибудь во время выполнения или запуска, указывая, что не было найдено никакой зависимости для FirstService
.
Допустим, мы поставили @ApplicationScoped
на FirstService
. Это сделает FirstService
в основном синглтоном (опять же, сохраняя его простым). Но подождите, вы говорите, что насчет HttpServletRequest
? В какой сфере это будет? Ответ: вы, как потребитель, не знаете, и вам все равно. (Реальным ответом будет, конечно, то, что он будет отражать текущий запрос, поэтому, по всей вероятности, находится в области действия запроса.) Каждый раз, когда вы пытаетесь получить доступ к этому полю HttpServletRequest
, вам лучше быть в запросе, или он взорвется вверх на вас.
Или вы можете поставить @RequestScoped
на FirstService
, и в этом случае все, что обращается к полю с типом FirstService
, должно быть лучше в активной области запроса во время доступа, или, опять же, все это взорвется от вас.
Наконец, вы делаете все это в контексте JAX-RS, у которого была собственная структура внедрения зависимостей до появления CDI. Для того, чтобы JAX-RS и CDI играли вместе достаточно красиво, требовалось много колотых квадратных колышков в круглых отверстиях. Одним из таких случаев является то, что, строго говоря, классы ресурсов не поддерживают инъекцию конструктора в стиле CDI, только инъекцию конструктора в стиле JAX-RS, которая является собственной (устаревшей) темой. Таким образом, с классами ресурсов вы, как правило, хотите остаться с внедрением поля.
Кроме того, приложения JAX-RS не требуют конструкций Servlet. Фактически, в зависимости от конкретной комбинации инфраструктуры, с которой вы работаете, @Inject private HttpServletRequest request
также может не работать, и вам, возможно, придется использовать @Context
. (Это его собственный набор вопросов и ответов.)