Spring IoC контейнер: использование стандартных аннотаций JSR 330, внедрение зависимостей с @Inject и @Named

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

Если вы используете 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, предоставляя доступ по требованию к bean-объектам более короткой области действия или отложенный доступ к другим bean-компонентам через вызов 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: MovieFinder


    fun listMovies() {
        movieFinder.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 не имеет обязательного атрибута. Следующая пара примеров показывает, как использовать @Inject и @Nullable:

Java

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
}


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки