有些人浅薄
有些人金玉其外而败絮其中
有一天
你会遇到一个彩虹般绚丽的人当你遇到这个人之后
会觉得其他人只是浮云而已
------《怦然心动》
目录
一.AutoWired
二.Resource
三.总结
一.AutoWired 使用该注解实现Bean的自动装配,默认按类型匹配,可以使用@Qualifier指定Bean的名称
使用该注解实现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实现类,会抛出异常;