1.成员变量注入

@RestController
public class StudentController{
    @Autowired
    private LiSi liSi;

	@GetMapping("/say")
    public String say() {
        return liSi.say();
    }
}

2.构造函数注入

方式一: 普通的构造方法
@RestController
public class StudentController{
    private LiSi liSi;
    @Autowired
    public StudentController(LiSi liSi){
        this.liSi = liSi;
    }

	@GetMapping("/say")
    public String say() {
        return liSi.say();
    }
}

方式二:lombok注解实现构造函数的注入
@RestController
@AllArgsConstructor
public class StudentController{
    // 变量需要被final修饰
    private final LiSi liSi;

	@GetMapping("/say")
    public String say() {
        return liSi.say();
    }
}

3. setter方法注入

@RestController
public class StudentController{
    private LiSi liSi;
    @Autowired
    public void setLiSi(LiSi liSi){
        this.liSi = liSi;
    }

	@GetMapping("/say")
    public String say() {
        return liSi.say();
    }
}

4. 结合@Qualifier使用的情况

前提:
	ZhangSan和LiSi两个Bean对象都被Spring的IOC管理,并且两者都实现相同的接口Student。

情况一:
	public class StudentController{
	    @Qualifier("liSi")
	    @Autowired
	    private Student student;

		@GetMapping("/say")
    	public String say() {
        	return student.say();
    	}
	}
	此时注入到StudentController中的其实是liSi,如果不加@Qualifier的话通过类型会找到
	两个bean,无法确定,这个时候spring会根据名字去找,通过字段名student找也找不到对应
	bean,最后报错。
	
情况二:
	public class StudentController{
	    @Autowired
	    private Student liSi;
	    
		@GetMapping("/say")
    	public String say() {
        	return liSi.say();
    	}
	}
	这种写法也可以,先通过类型找到两个bean对象,再通过字段名liSi找到一个对应的bean
	注入成功。这种写法对于字段名称的定义较严格,一般是注入对象的首字母小写。

5. 总结

  • Spring中Autowired注入的两种方式:
byType:默认是按照类型注入,与bean的属性具有相同类型的其他bean自动装配到bean
        的对应属性中。
        
byName:与bean的属性具有相同名字的其他bean,自动装配到对应的属性中。
        (名字一般为首字母小写,例如:LiSi 在 容器中的名字为 liSi)
  • 装配过程总结:
1. 找不到任何bean时直接报错
2. 找到一个,直接注入
3. 同一个类型找到多个时,按类型注入已经不可能;此时spring会再次按照名称注入,如果
   没有同名的bean就报错。
4. 通过@Qualifier可以对注入的过程有更多的控制,当有多个相同类型的bean时可通过
   @Qualifier来指定名称;或者直接将属性名定义为和要注入的bean一样的名称也可以
   实现注入。

6. 用到的实体

  • LiSi:(适用于1、2、3)
import org.springframework.stereotype.Component;
/**
 * @author gxn
 */
@Component
public class LiSi{
    public String say() {
        return "I am Li Si!";
    }
}
  • ZhangSan:(适用于1、2、3)
import org.springframework.stereotype.Component;
/**
 * @author gxn
 */
@Component
public class ZhangSan{
    public String say() {
        return "I am Zhang San!";
    }
}
  • Student:
import org.springframework.stereotype.Component;
/**
 * @author gxn
 */
@Component
public interface Student {
    /**
     * 学生的说话方法
     * @return
     */
    public String say();
}

注意: 为验证4中的场景对LiSi和ZhangSan做了调整,让他们去实现Student,模拟通过类型找到两个bean的情况。

  • 修改后的LiSi:(适用于4)
import org.springframework.stereotype.Component;
/**
 * @author gxn
 */
@Component
public class LiSi implements Student{
    @Override
    public String say() {
        return "I am Li Si!";
    }
}
  • 修改后的ZhangSan:(适用于4)
import org.springframework.stereotype.Component;
/**
 * @author gxn
 */
@Component
public class ZhangSan implements Student{
    @Override
    public String say() {
        return "I am Zhang San!";
    }
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐