@AutoWired与@Resource区别

@AutoWired与@Resource区别,第1张

@AutoWired与@Resource区别

有些人浅薄

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

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

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

只是浮云而已

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

目录

一.AutoWired

二.Resource

三.总结


一.AutoWired

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

写个普普通通的接口

@RestController
public 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);

}
@Service
public 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实现类呢,再创建一个实现类如下,

@Service
public 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注入的时候需要另外指明要使用的是哪一个实现类。

改动如

@RestController
public 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如下

@Resource
private 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实现类,会抛出异常;

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5722367.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存