前言:
在日常的开发项目当中,这两个注解是经常会用到的,但是在实际使用当中好像使用起来并没有多大区别,这里我就对这两个注解进行一个详细的区别总结,通过一个完整的典型例子进行论证,思路清晰明了。
目录
一、结论
二、典型案例
(一)、准备代码
(二)、使用@Autowired默认进行注入
(三)、使用@Autowired+@Qualifier进行注入
(四)、使用@Resource默认进行注入
(五)、使用@Resource指定名称进行注入
三、结语
先说结论:
1、@Autowired默认是根据类型(ByType)注入的,@Resource默认是根据名称(ByName)注入的。
2、@Autowired是Spring提供的注解,@Resource是JDK提供的注解
3、当一个接口存在多个实现类,@Autowired和@Resource都是需要指定Bean的名称才能完成注入,@Autowired可通过@Qualifier来只能Bean的名称进行注入,@Resource则可通过name来完成Bean的注入。
这里我搭建了一个简单的springboot项目,并写了一个接口和其对应的两个实现类,来具体通过代码来证明以上的结论。
UserService接口:
package com.ithuang.demo.service;
public interface UserService {
public void insert();
}
UserServiceImpl实现类
package com.ithuang.demo.service.serviceImpl;
import com.ithuang.demo.service.UserService;
import org.springframework.stereotype.Service;
@Service("service")
public class UserServiceImpl implements UserService {
@Override
public void insert() {
System.out.println("方法1:执行了插入操作...");
}
}
UserServiceImpl2实现类
package com.ithuang.demo.service.serviceImpl;
import com.ithuang.demo.service.UserService;
import org.springframework.stereotype.Service;
@Service("service2")
public class UserServiceImpl2 implements UserService {
@Override
public void insert() {
System.out.println("方法2:执行了插入操作...");
}
}
单元测试
package com.ithuang.demo;
import com.ithuang.demo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
@Autowired
private UserService userService;
@Test
void test() {
userService.insert();
}
}
运行结果
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.ithuang.demo.DemoApplicationTests': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.ithuang.demo.service.UserService' available: expected single matching bean but found 2: userServiceImpl,userServiceImpl2
大概意思就是说在使用@Autowired进行注入的时候,默认根据了类型进行了注入,并没有指定Bean的名称,导致了Spring容器发现了两个Bean,从而不知道注入哪个Bean。
单元测试
package com.ithuang.demo;
import com.ithuang.demo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
@Autowired
@Qualifier("service2")
private UserService userService;
@Test
void test() {
userService.insert();
}
}
运行结果
方法2:执行了插入操作...
这次便成功完成了注入并且在控制台输出了第二个实现类当中的方法,通过@Qualifier来指定Bean的名称进行了注入。
单元测试
package com.ithuang.demo;
import com.ithuang.demo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
class DemoApplicationTests {
@Resource
private UserService userService;
@Test
void test() {
userService.insert();
}
}
运行结果
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.ithuang.demo.DemoApplicationTests': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.ithuang.demo.service.UserService' available: expected single matching bean but found 2: service,service2
还是和之前一样的问题,因为@Resource并没有通过name指向具体的Bean,导致无法完成注入。
单元测试
package com.ithuang.demo;
import com.ithuang.demo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
class DemoApplicationTests {
@Resource(name = "service")
private UserService userService;
@Test
void test() {
userService.insert();
}
}
运行结果
方法1:执行了插入操作...
这次控制台正常输入,通过name指定Bean的名称来完成注入即可。
以上就是我对@Autowired和@Resource两个在工作当中经常用到的注解的理解和分享。