直接看原文
原文链接:
【精选】@Autowired和@Resource注解的区别和联系【精选】
-------------------------------------------------------------------------------------------------------------------------------
先说联系
注意:如果声明在字段上,那么就不需要再写setter方法。但是本质上,该对象还是作为set方法的实参,通过执行set方法注入,只是省略了setter方法罢了
对于byName和byType方式不太熟悉的可以看一下这里:Spring中的byName与byType
简单来说,byName就是变量名去匹配bean的id属性,而byType则是变量类型去匹配bean的class属性
- <bean id="userService" class="com.test.UserServiceImpl">
- </bean>
- @Autowired
- private UserService userService;
此处byName就是拿变量名userService
去匹配IOC容器的iduserService
,匹配成功;而byType就是拿变量类型UserService
去匹配IOC容器的idcom.test.UserService.UserServiceImpl
,因为UserServiceImpl是UserService实现,所以也匹配成功
接下来再分别讲讲@Autowired注解和@Resource注解的使用
步骤:@Autowird默认的注入方式为byType,也就是根据类型匹配,当有多个实现时,则通过byName注入,也可以通过配合@Qualifier注解来显式指定name值,指明要使用哪个具体的实现类
举例:
首先有一个接口UserService和两个实现类UserServiceImpl1和UserServiceImpl2,并且这两个实现类已经加入到Spring的IOC容器中了
- @Service
- public class UserServiceImpl1 implements UserService
-
- @Service
- public class UserServiceImpl2 implements UserService
在spring容器中的配置体现就是下面的, 下面的id默认就是类名首字母的小写,class就是全类名.
- <bean id="userServiceImpl1 " class="com.test.UserServiceImpl1">
- </bean>
- <bean id="userServiceImpl2 " class="com.test.UserServiceImpl2">
- </bean>
通过@Autowired注入使用
- @Autowired
- private UserService userService;
根据上面的步骤,可以很容易判断出,直接这么使用是会报错的
原因:首先通过byType注入(就是拿UserService去容器里找有么有UserService或者实现类是UserService的),判断UserService类型有两个实现,无法确定具体是哪一个,于是通过byName方式(就是拿变量名去和容器里id比较),这里的变量名userService也无法匹配IOC容器中id(此处指的userServiceImpl1和userServiceImpl2),于是报错。
注意:通过注解注入到IOC容器的id值默认是其类名首字母小写
解决方案
方式一:
- // 方式一:改变变量名
- @Autowired
- private UserService userServiceImpl1;
方式二:
- // 方式二:配合@Qualifier注解来显式指定name值
- @Autowired
- @Qualifier(value = "userServiceImpl1")
- private UserService userService;
步骤:@Resource默认通过byName注入,如果没有匹配则通过byType注入
举例:
- @Service
- public class UserServiceImpl1 implements UserService
-
- @Service
- public class UserServiceImpl2 implements UserService
- @Resource
- private UserService userService;
首先通过byName匹配,变量名userService无法匹配IOC容器中任何一个id(这里指的userServiceImpl1和userServiceImpl2),于是通过byType匹配,发现类型UserService的实现类有两个,仍然无法确定,于是报错。
同时@Resource还有两个重要的属性:name和type,用来显式指定byName和byType方式注入
使用:对应4种情况
- // 1. 默认方式:byName
- @Resource
- private UserService userDao;
-
- // 2. 指定byName
- @Resource(name="userService")
- private UserService userService;
-
- // 3. 指定byType
- @Resource(type=UserService.class)
- private UserService userService;
-
- // 4. 指定byName和byType
- @Resource(name="userService",type=UserService.class)
- private UserService userService;