欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

@AutoWired与@Resource区别

时间:2023-08-06

有些人浅薄

有些人金玉其外而败絮其中

有一天
你会遇到一个彩虹般绚丽的人

当你遇到这个人之后
会觉得其他人

只是浮云而已

------《怦然心动》

目录

一.AutoWired

二.Resource

三.总结


一.AutoWired

使用该注解实现Bean的自动装配,默认按类型匹配,可以使用@Qualifier指定Bean的名称

写个普普通通的接口

@RestControllerpublic class UserController { @Autowired private UserService userService; @PostMapping("/login") public String login(String name, String password) { User userBean = userService.loginIn(name, password); if (userBean != null) { return "success"; } else { return "error"; } }}

public interface UserService { User loginIn(String name, String password);}

@Servicepublic class UserServiceImpl implements UserService { //将DAO注入Service层 @Resource private UserMapper userMapper; @Override public User loginIn(String name, String password) { return userMapper.getInfo(name, password); }}

Dao层略,只看controller与server层。

如上,使用AutoWired,从Spring容器中获取UserService实现类,注入该属性,byType-根据类型注入。

运行成功

然后根据这个说法,做个实验,既然是获取UserService这个接口的实现类,那么如果有多个UserService实现类呢,再创建一个实现类如下,

@Servicepublic class testServiceImpl implements UserService { @Override public User loginIn(String name, String password) { return null; }}

然后我再次运行代码看看会报什么错?

然后代码运行,直接报错如下,匹配到了两个,找不到单个的来匹配。

Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.demo.service.UserService' available: expected single matching bean but found 2: userServiceImpl,testServiceImpl

原因是如果有两个实现类,不管是service还是dao层的,如果都implements同一个接口,那么当使用AutoWired注入的时候需要另外指明要使用的是哪一个实现类。

改动如

@RestControllerpublic class UserController { @Autowired @Qualifier("userServiceImpl") //指定bean名称,默认开头小写 private UserService userService; @PostMapping("/login") public String login(String name, String password) { User userBean = userService.loginIn(name, password); if (userBean != null) { return "success"; } else { return "error"; } }}

这里使用了Qualifier指定了我要使用UserServiceImpl这个实现类的bean名称,然后注意开头默认小写才能注入进来,否则代码报红。

然后启动正常运行,图略。

二.Resource

继续复用上面的代码,将testServiceImpl注释掉,改成resource如下

@Resourceprivate UserService userService;

正常运行,图略。

现在将testServiceImpl放开呢?

答案是肯定的,与上面的报错提示一致。

匹配到了两个,找不到单个的来匹配。

所以解决如下,给实现类取个名字,比如:

@Service("userService")public class UserServiceImpl implements UserService {}

由于在controller层注入的名字叫做userService,

private UserService userService;

所以得给该实现类取个一样名字的,否则代码运行报错。所以这里可以看出该注解先根据名称注入。


再做个实验,如果就不想给实现类指定名字,可以在@Resource注解后面指定,如下

@Resource(name = "userServiceImpl")private UserService userService;

这里的名字也就是实现类的名字,但是开头得小写,否则提示找不到。

还有一种type的指定方式,如下

@Resource(type = UserServiceImpl.class)private UserService userService;

这两种方式都是为了定位到那一个具体的实现类,都能正常运行。

三.总结

byType:意思是根据实现类注入,如果有多个实现类,那么具体需要指定一个。

@AutoWired:

默认从Spring容器中获取UserService实现类,注入该属性,byType-根据类型注入;

如果Spring容器中有多个UserService实现类,会抛出异常;

可以使用@Qualifier("userServiceImpl"),指定需要的bean;

@Resouce

默认从Spring容器中获取名为userService的bean,注入该属性,byName-根据名称注入;

如果找不到名为userService的bean,接着会去找UserService的实现类,然后byType注入;

如果Spring容器中有多个UserService实现类,会抛出异常;

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。