Начиная со Spring 3.0, Spring предлагает поддержку аннотаций из JSR-330 (Внедрение зависимостей). Эти аннотации сканируются так же, как и аннотации Spring. Чтобы использовать их, вам необходимо иметь соответствующие jar-файлы в вашем пути классов.

Если вы используете Maven, артефакт javax.inject находится в стандартном репозитории Maven ( https://repo1.maven.org/maven2/javax/inject/javax.inject/1/). Вы можете добавить следующую зависимость в свой файл pom.xml:

<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>

Внедрение зависимостей с помощью @Inject и @Named

Вместо @Autowired вы можете использовать @javax.inject.Inject следующим образом:

Java
import javax.inject.Inject;
public class SimpleMovieLister {
    private MovieFinder movieFinder;
    @Inject
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
    public void listMovies() {
        this.movieFinder.findMovies(...);
        // ...
    }
}
Kotlin
import javax.inject.Inject
class SimpleMovieLister {
    @Inject
    lateinit var movieFinder: MovieFinder
    fun listMovies() {
        movieFinder.findMovies(...)
        // ...
    }
}

Как и в случае с @Autowired, вы можете использовать @Inject на уровне поля, метода и аргумента конструктора. Более того, вы можете объявить свою точку внедрения как Provider, что позволит получить доступ по требованию к бинам с более узкой областью видимости или отложенный доступ к другим бинам через вызов Provider.get(). В следующем примере предложен вариант предыдущего примера:

Java
import javax.inject.Inject;
import javax.inject.Provider;
public class SimpleMovieLister {
    private Provider<MovieFinder> movieFinder;
    @Inject
    public void setMovieFinder(Provider<MovieFinder> movieFinder) {
        this.movieFinder = movieFinder;
    }
    public void listMovies() {
        this.movieFinder.get().findMovies(...);
        // ...
    }
}
Kotlin
import javax.inject.Inject
class SimpleMovieLister {
    @Inject
    lateinit var movieFinder: Provider<MovieFinder>
    fun listMovies() {
        movieFinder.get().findMovies(...)
        // ...
    }
}

Если необходимо использовать полное имя для зависимости, которую нужно внедрить, вам потребуется использовать аннотацию @Named, как показано в следующем примере:

Java
import javax.inject.Inject;
import javax.inject.Named;
public class SimpleMovieLister {
    private MovieFinder movieFinder;
    @Inject
    public void setMovieFinder(@Named("main") MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
    // ...
}
Kotlin
import javax.inject.Inject
import javax.inject.Named
class SimpleMovieLister {
    private lateinit var movieFinder: MovieFinder
    @Inject
    fun setMovieFinder(@Named("main") movieFinder: MovieFinder) {
        this.movieFinder = movieFinder
    }
    // ...
}

Как и @Autowired, @Inject также можно использовать с java.util.Optional или @Nullable. Это тем более применимо в данном случае, поскольку @Inject не имеет required атрибута. Следующая пара примеров показывает, как использовать @Inject и @Nullable:

public class SimpleMovieLister {
    @Inject
    public void setMovieFinder(Optional<MovieFinder> movieFinder) {
        // ...
    }
}
Java
public class SimpleMovieLister {
    @Inject
    public void setMovieFinder(@Nullable MovieFinder movieFinder) {
        // ...
    }
}
Kotlin
class SimpleMovieLister {
    @Inject
    var movieFinder: MovieFinder? = null
}

@Named и @ManagedBean: Стандартные эквиваленты аннотации @Component

Вместо @Component можно использовать @javax.inject.Named или javax.annotation.ManagedBean, как показано в следующем примере:

Java
import javax.inject.Inject;
import javax.inject.Named;
@Named("movieListener")  // можно также использовать @ManagedBean("movieListener")
public class SimpleMovieLister {
    private MovieFinder movieFinder;
    @Inject
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
    // ...
}
Kotlin
import javax.inject.Inject
import javax.inject.Named
@Named("movieListener")  // можно также использовать @ManagedBean("movieListener")
class SimpleMovieLister {
    @Inject
    lateinit var movieFinder: MovieFinder
    // ...
}

Очень часто используется @Component без указания имени компонента. Аналогичным образом можно использовать @Named, как показано в следующем примере:

Java
import javax.inject.Inject;
import javax.inject.Named;
@Named
public class SimpleMovieLister {
    private MovieFinder movieFinder;
    @Inject
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
    // ...
}
Kotlin
import javax.inject.Inject
import javax.inject.Named
@Named
class SimpleMovieLister {
    @Inject
    lateinit var movieFinder: MovieFinder
    // ...
}

Если вы задействуете @Named или @ManagedBean, то использовать сканирование компонентов можно точно так же, как и при использовании аннотаций Spring, как показано в следующем примере:

Java
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig  {
    // ...
}
Kotlin
@Configuration
@ComponentScan(basePackages = ["org.example"])
class AppConfig  {
    // ...
}
В отличие от @Component, аннотации @Named из JSR-330 и @ManagedBean из JSR-250 не являются составными. Для создания специальных аннотаций компонентов следует использовать модель стереотипов Spring.

Ограничения стандартных аннотаций JSR-330

При работе со стандартными аннотациями следует знать, что некоторые важные функции будут недоступны, как показано в следующей таблице:

Таблица 6. Элементы компонентной модели Spring в сравнении с вариантами из JSR-330
Spring javax.inject.* ограничения/комментарии javax.inject

@Autowired

@Inject

У @Inject нет атрибута "required". Вместо этогоможно использовать Optional из Java 8

@Component

@Named / @ManagedBean

JSR-330 не предоставляет составную модель, только способ идентификации именованных компонентов.

@Scope("singleton")

@Singleton

Область доступности по умолчанию из JSR-330 похожа на область доступности на уровне prototype из Spring. Однако для того, чтобы соответствовать общим настройкам Spring, бин из JSR-330, объявленный в контейнере Spring, по умолчанию является singleton. Чтобы использовать область доступности , отличную от singleton, необходимо использовать аннотацию @Scope из Spring. javax.inject также предоставляет возможность использовать аннотацию @Scope. Тем не менее, она предназначена только для создания собственных аннотаций.

@Qualifier

@Qualifier / @Named

javax.inject.Qualifier – это просто мета-аннотация для создания кастомных квалификаторов. Конкретные String квалификаторы (наподобие @Qualifier из Spring с некоторым значением) могут быть связаны через javax.inject.Named.

@Value

-

без эквивалента

@Required

-

без эквивалента

@Lazy

-

без эквивалента

ObjectFactory

Provider

javax.inject.Provider является прямой альтернативой ObjectFactory из Spring , только с более коротким именем метода get(). Его также можно использовать в сочетании с @Autowired из Spring или с неаннотированными конструкторами и сеттерами.