官方文档5.3.3:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-dependencies
// Zhangsan
@Component
public class Zhangsan {
public void say(){
System.out.println("say hello,i am zhangsan");
}
}
// Lisi
@Component
public class Lisi {
public void say(){
System.out.println("say hello,i am lisi");
}
}
// HelloController
@RestController
public class HelloController {
@GetMapping("/hello")
public String getHello(){
return "hello world;";
}
}
可以看到Zhangsan 、Lisi两个类上都打上了@Component注解,该注解将某个类声明为一个Spring的bean, 然后将其加入到Spring容器中,这是实现注入的前提。(Service、Controller等注解实现注入同样依赖于Component注解)
Bean的注入通常使用@Autowired注解,该注解用于bean的field、setter方法以及构造方法上,显式地声明依赖。 在最新的文档中注入方式有两大类:
但是通常认为还有一种是基于成员变量的依赖注入(spring framerwork 4.0后不推荐使用)
public class HelloController {
@Autowired //idea会有一个黄色的波浪线提示Field injection is not recommended(不再推荐使用字段注入)
private Lisi lisi;
@GetMapping("/hello")
public String getHello(){
lisi.say();
return "hello world;";
}
}
public class HelloController {
private Lisi lisi;
@Autowired //这里的Autowired可以加也可以不加,但是建议加上
public HelloController(Lisi lisi){
this.lisi = lisi;
}
@GetMapping("/hello")
public String getHello(){
lisi.say();
return "hello world;";
}
}
@RequiredArgsConstructor
@RestController
public class HelloController {
// @Autowired
private final Lisi lisi;
@GetMapping("/hello")
public String getHello(){
lisi.say();
return "hello world;";
}
}
public class HelloController {
// @Autowired
private Lisi lisi;
@Autowired
public void setLisi(Lisi lisi) {
this.lisi = lisi;
}
@GetMapping("/hello")
public String getHello(){
lisi.say();
return "hello world;";
}
}
首先改造一下我们的项目,将Zhangsan和Lisi两个类继承于Person接口(需要新建),看看运行效果
//person
public interface Person {
void say();
}
//zhangsan lisi
public class Lisi implements Person{
public void say(){
System.out.println("say hello,i am lisi");
}
}
//hellocontroller
@RequiredArgsConstructor
@RestController
public class HelloController {
private final Person zhangsan;
@GetMapping("/hello")
public String getHello(){
zhangsan.say();
return "hello world;";
}
}
上面四个情景展现了Spring中Autowired的两种方式
装配方式总结:
技巧:使用@Qualifier @Qualifier注解是和@Autowired一起使用的。使用此注解可以让你对注入的过程有更多的控制。@Qualifier可以被用在单个构造器或者方法的参数上。当上下文有几个相同类型的bean, 使用@Autowired则无法区分要绑定的bean,此时可以使用@Qualifier来指定名称。
//say hello,i am zhangsan
@RestController
public class HelloController {
@Qualifier("zhangsan")
@Autowired
private Person person;
@GetMapping("/hello")
public String getHello(){
person.say();
return "hello world;";
}
}
@RequiredArgsConstructor
@RestController
public class HelloController {
@Qualifier("zhangsan")
private final Person person;
@GetMapping("/hello")
public String getHello(){
person.say();
return "hello world;";
}
}
如果你想同时使用RequiredArgsConstructor和Qualifier,仅仅写成下面这样还是不行的,需要在项目根目录下新建 lombok.config并写入
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier