Поговорите об аннотациях внедрения зависимостей @Resource и @Autowired

Spring Boot Java

1. Введение

@Resourceи@AutowiredАннотации можно найти вSpring FrameworkДекларативное внедрение зависимостей в приложения. И точки знаний этих двух аннотаций часто задействованы в интервью. Сегодня мы их подытожим.

2. @Resource

полное имяjavax.annotation.Resource,это принадлежитJSR-250Аннотация к спецификации, содержащаяJakarta EE(J2EE)середина.SpringОбеспечена поддержка этой аннотации. Давайте подробнее рассмотрим правила для этой аннотации.

Эта аннотация используется для свойств членов и методов установки. по умолчанию@ResourceВ соответствии с внедрением имени, если имя не объявлено явно, оно вводится в соответствии с именем переменной или соответствующим именем параметра в методе.

Resource注解流程

Если мы хотим реализовать полиморфизм в целевом компоненте, мы можем написать:

/**
 * 多态的体现.
 *
 * @author felord.cn
 * @since 9 :26
 */
@Component
public class ResourceTest {
    @Resource
    private ApplicationRunner applicationRunner;    
    @Resource
    private ApplicationRunner runner;
    // ...
}

Ограничения квалификатора см.Spring аннотация @Qualifier подробный анализ

3. @Autowired

@AutowiredОбычно применяется к конструкторам, переменным-членам и методам. Его механизм таков:

Autowired流程

Об этой аннотации нужно говорить, а частота ежедневного использования достаточно высока.

3.1 Аннотация к конструкции

через цельBeanВы можете ввести соответствующийBean.

package cn.felord;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

/**
 * @author felord.cn
 * @since 9:26
 **/
@Component
public class AutowiredTest {
 private final ApplicationRunner applicationRunner;

    @Autowired
    public AutowiredTest(ApplicationRunner applicationRunner) {
        this.applicationRunner = applicationRunner;
    }
}

отSpring Framework 4.3Начинать,@AutowiredЕсли целевой компонент определяет только один конструктор, то больше нет необходимости добавлять в этот конструктор@Autowiredаннотация. Если у целевого компонента есть несколько доступных конструкторов и нет основного конструктора/конструктора по умолчанию, по крайней мере один конструктор должен быть@AutowiredФлаг, указывающий, какой конструктор использовать контейнером Spring IoC.

3.2 Аннотация к переменным-членам

и@ResourceТакой же,@Autowiredтакже может быть помечен в цельBeanна переменные-члены.

/**
 * @author felord.cn
 * @since 9:26
 **/
@Component
public class AutowiredTest {
    @Autowired
    private ApplicationRunner applicationRunner;
    
    // ...
    
}

3.3 Аннотация к методу

Как правило, сеттерные методы используются чаще. и@AutowiredПоддерживает ввод нескольких параметров.

/**
 * The type Autowired test.
 *
 * @author felord.cn
 * @since 9 :26
 */
@Component
public class AutowiredTest {

    private ApplicationRunner applicationRunner;
    private EmployeeMapper employeeMapper;
    private DepartmentMapper departmentMapper;

    /**
     * Sets application runner.
     *
     * @param applicationRunner the application runner
     */
    @Autowired
    public void setApplicationRunner(ApplicationRunner applicationRunner) {
        this.applicationRunner = applicationRunner;
    }


    /**
     * 支持多参数
     *
     * @param employeeMapper   the employee mapper
     * @param departmentMapper the department mapper
     */
    @Autowired
    public void prepare(EmployeeMapper employeeMapper, DepartmentMapper departmentMapper) {
        this.employeeMapper = employeeMapper;
        this.departmentMapper = departmentMapper;
    }

}

Как вы думаете, это закончилось? Следующий метод оценивается, что большинству людей все равно.

/**
 * The type Autowired test.
 *
 * @author felord.cn
 * @since 9 :26
 */
@Component
public class AutowiredTest {
    // 注入 数组
    @Autowired
    private MovieCatalog[] movieCatalogs;
    
    private Map<String, Movie> movies;
    
    private Set<CustomerPreferenceDao> customerPreferenceDaos;
    
    // 注入 set
    @Autowired
    public MovieRecommender(Set<CustomerPreferenceDao> customerPreferenceDaos) {
        this.customerPreferenceDaos = customerPreferenceDaos;
    }
            
    // 注入 map 
    @Autowired
    public void setMovieCatalogs(Map<String, Movie> movies) {
        this.movies = movies;
    }
   
    // ...
}

Bean-компоненты могут быть внедрены в контейнеры массива и коллекции целевого Bean-компонента. По умолчанию автосвязывание завершится ошибкой, если для данной точки внедрения нет подходящих компонентов-кандидатов. Должен быть хотя бы один соответствующий элемент.

Если вы хотите, чтобы элементы сортировались в определенном порядке, bean-компонент element может реализоватьorg.springframework.core.OrderedИнтерфейс или соответствующая аннотация@Orderили стандартный@Priority. На основании некоторых механизмов не рекомендуется использовать аннотации для сортировки, иначе ожидаемые ожидания не могут быть достигнуты.Рекомендуется использовать интерфейсOrdered.

3.4 Дополнительная сборка

@ResourceНет функции для предоставления дополнительной сборки, и если сборка невозможна, будет выдано исключение; а также@Autowiredпри условииrequiredсвойство (по умолчаниюtrue), чтобы избежать этого, установите@Autowiredзаfalse.

/**
 * The type Autowired test.
 *
 * @author felord.cn
 * @since 9 :26
 */
@Component
public class AutowiredTest {
    // 一旦找不到 movieFinder  不会异常  而初始化为 null
    @Autowired(required = false)
    private MovieFinder movieFinder;
    // ...
}

Здесь также есть операция фарса, вы можете ее игнорировать.requiredАтрибуты. пройти черезJava 8изjava.util.Optionalчтобы указать, что компонент-кандидат является необязательным.

/**
 * The type Autowired test.
 *
 * @author felord.cn
 * @since 9 :26
 */
@Component
public class AutowiredTest {
public class SimpleMovieLister {
    // 使用 Optional 表明候选Bean可选
    @Autowired
    public void setMovieFinder(Optional<MovieFinder> movieFinder) {
     //   ...
    }
}

отSpring 5.0для начала вы также можете использовать@NullableАннотация, вы можете реализовать логику обнаружения самостоятельно или использовать эту аннотацию напрямуюJSR-305который предоставилjavax.annotation.Nullable.

/**
 * The type Autowired test.
 *
 * @author felord.cn
 * @since 9 :26
 */
@Component
public class AutowiredTest {
public class SimpleMovieLister {
    // 使用 @Nullable 注解表明候选Bean可选
    @Autowired
    public void setMovieFinder(@Nullable MovieFinder movieFinder) {
      //  ...
    }
}

4. @Inject

отSpring 3.0Начинать,SpringобеспечиватьJSR-330Поддержка стандартных аннотаций (внедрение зависимостей). Вам нужно импортировать зависимости:

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

Затем вы можете использовать соответствующие аннотации для внедрения зависимостей, основные аннотации:@javax.inject.Inject. В большинстве случаев эту аннотацию можно использовать вместо@Autowiredиспользовать, но@Injectнетrequiredимущества, но также может сочетаться сjava.util.Optionalили использовать@Nullableдля достижения того же эффекта.

В большинстве случаев лишнее введение никому не нравится.Jakarta EEЗависимость от использования уже существующей функции,SpringзаблокированJakarta EEЭкология инъекции зависимостей.

5. Резюме

@Resourceи@Autowiredнаходятся в разном порядке приоритета (см. выше) и дополнительно@ResourceпринадлежатьJakarta EEнормативный@AutowiredпринадлежатьSpringкатегория,@Resourceнельзя использовать в параметрах конструкции,@Autowiredслужба поддержкиrequiredАтрибуты. С объектно-ориентированной точки зрения,@Resourceбольше подходит для мелкозернистого внедрения полиморфизма, в то время как@AutowiredБолее одноэлементная инъекция сосредоточена на полиморфизме.@InjectНет необходимости обсуждать слишком много, просто в качестве бонуса. Ну вот и все на сегодня, уделяйте больше внимания:Код Фермер Маленький Толстый Брат, больше обмена знаниями о галантерее.

关注公众号:Felordcn获取更多资讯

Личный блог: https://felord.cn