Советы по впрыску Spring @Autowired

задняя часть Spring
Советы по впрыску Spring @Autowired

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

1. Один и тот же тип вводится несколько раз для одного и того же экземпляра

Сначала давайте посмотрим, что это за код?

@Autowired
private XiaoMing xiaoming;

@Autowired
private XiaoMing wanger;

XiaoMing.java

package com.example.demo.beans.impl;

import org.springframework.stereotype.Service;

/**
 * 
 * The class XiaoMing.
 *
 * Description:小明
 *
 * @author: huangjiawei
 * @since: 2018年7月23日
 * @version: $Revision$ $Date$ $LastChangedBy$
 *
 */
@Service
public class XiaoMing {
    
    public void printName() {
    	System.err.println("小明");
    }
}

мы все знаем@Autowiredможет быть основан на типе (Type) для автоматического внедрения, а внедренный bean-компонент по умолчанию — это singleton (SingleTon), то мы можем спросить, не повторится ли указанная выше инъекция дважды? Ответ положительный. И каждый внедренный экземпляр является одним и тем же экземпляром. Ниже мы просто проверяем:

@RestController
public class MyController {
    
    @Autowired
    private XiaoMing xiaoming;
    
    @Autowired
    private XiaoMing wanger;
    
    @RequestMapping(value = "/test.json", method = RequestMethod.GET)
    public String test() {
    	System.err.println(xiaoming);
    	System.err.println(wanger);
    	return "hello";
    }
}

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

com.example.demo.beans.impl.XiaoMing@6afd4ce9
com.example.demo.beans.impl.XiaoMing@6afd4ce9

Во-вторых, экземпляр типа интерфейса инъекции

Если тип, который мы хотим внедрить, объявлен как тип интерфейса, и интерфейс имеет более одного класса реализации, будет ли работать следующий код? мы предполагаем, чтоStudentдля интерфейса,WangErиXiaoMingДля двух классов реализации.

@Autowired
private Student stu1;

@Autowired
private Student stu2;
@Service
public class XiaoMing implements Student {
@Service
public class WangEr implements Student {

Ответ заключается в том, что приведенный выше код не работает должным образом, и Spring также начинает сообщать об ошибке, потому что Spring хочетStudentБыл внедрен один экземпляр синглтона, но два были случайно найдены в процессе внедрения, поэтому было сообщено об ошибке. Конкретная информация об ошибке выглядит следующим образом:

Field stu1 in com.example.demo.controller.MyController required a single bean, but 2 were found:
	- wangEr: defined in file [C:\Users\huangjiawei\Desktop\demo\target\classes\com\example\demo\beans\impl\WangEr.class]
	- xiaoMing: defined in file [C:\Users\huangjiawei\Desktop\demo\target\classes\com\example\demo\beans\impl\XiaoMing.class]

Итак, как это сделать? В общем, мы думаем о присвоении значения id каждому классу реализации, что приводит к следующему коду:

@Autowired
private Student stu1;

@Autowired
private Student stu2;
@Service("stu1")
public class XiaoMing implements Student {
@Service("stu2")
public class WangEr implements Student {

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

3. Резюме

  • 1. Можно использовать тот же тип@AutowiredВнедрять несколько раз, и все внедренные экземпляры являются одним и тем же экземпляром;
  • 2. При инжекте интерфейса для каждого класса реализации должен быть указан соответствующий id, и Spring сообщит об ошибке;