@Autowired注解

@Autowired注解是Spring提供,只按照byType进行注入。@Autowired如果想要按照byName方式需要加@Qualifier,Qualifier意思是合格者,一般跟Autowired配合使用,需要指定一个bean的名称,通过bean名称就能找到需要装配的bean。

//定义一个服务,添加@Service交给Spring Boot管理
@Service
public class Service1 {
  
}
//在另一个Service中需要依赖,使用方法如下。
@Service
public class Service2 {
	@Autowired
	private Service1 service1;
}
@Service
public class Service2 {
       private final Service1 service1;
   
       @Autowired
	public void setService1(Service1 service1) {
		this.service1 = service1;
       }
}

流程图如下:

image-20220616235458482

@Autowired的高端玩法

其实上面举的例子都是通过@Autowired自动装配单个实例,但这里我会告诉你,它也能自动装配多个实例,怎么回事呢?

将UserService方法调整一下,用一个List集合接收IUser类型的参数:

@Service
public class UserService {

    @Autowired
    private List<IUser> userList;

    @Autowired
    private Set<IUser> userSet;

    @Autowired
    private Map<String, IUser> userMap;

    public void test() {
        System.out.println("userList:" + userList);
        System.out.println("userSet:" + userSet);
        System.out.println("userMap:" + userMap);
    }
}

增加一个controller:

@RequestMapping("/u")
@RestController
public class UController {

    @Autowired
    private UserService userService;

    @RequestMapping("/test")
    public String test() {
        userService.test();
        return "success";
    }
}

调用该接口后:

img

从上图中看出:userList、userSet和userMap都打印出了两个元素,说明@Autowired会自动把相同类型的IUser对象收集到集合中。

@Resource注解

@Resource注解是Java标准库提供。默认采用byName方式进行注入,如果找不到则使用byType。可通过注解参数进行改变。比起Autowired好处在于跟Spring的耦合度没有那么高。

//定义一个服务,添加@Service交给Spring Boot管理
@Service
public class Service1 {
}
//在另一个Service中需要依赖,使用方法如下。
@Service
public class Service2 {
@Resource
private Service1 service1;
}

流程图如下:

在这里插入图片描述

构造参数注入

比起以上两种方式,Spring更推荐以下方式进行注入,因为以上两种通过反射将对象直接注入私有属性,会破环封装性。

使用构造参数注入能够及时发现循环依赖,使用注解注入Spring会帮你解决循环以案例问题,但是在开发中,应该避免循环依赖,如果存在这种问题那么说明系统设计的有问题,需要及时修改。

@Service
public class Service2 {
       private final Service1 service1;
	//Spring Boot在进行解析时,会自动将Service1的单例对象进行注入
	public Service2(Service1 service1) {
		this.service1 = service1;
	}
}

原文: