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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值