你真的了解Autowired和Resouce吗

背景:自己最近在看《升入浅出springBoot2.X》,里面提到getBean方法,刚好联想到Autowired和Resouce两个注解。(如果想要这本书的pdf,可以在下面留下邮箱)

这篇文章会分为下面三个部分。1,2部分在网上很多,但是鉴于文章的完整性,这里还是写一下,之所以要写这篇文章主要是因为网上很少有分析原因的,大多都是用法和区别。我就在这里抛钻引钰,如果有不正确的地方还望各位大佬多多指出。

1.Autowired和Resouce的用法。

    @Autowired

    本着代码是程序员最直接的交流语言,我这里直接上代码。

@Service
public class BussionPerssion implements Perssion {
    @Autowired
    Animal animal;

    @Override
    public void service() {
        animal.use();
    }
}

   BussionPerssion里面有animal属性,然后借助animal的use方法对外提供服务。

@Service("dog")
public class Dog implements Animal {

    @Override
    public void use() {
        System.out.println("dog is a dog!");
    }

}

    Dog实现Animal接口,并由@service修饰。这样我们就可以在BussionPerssion中调用Dog的方法了。

    这个时候问题来了,如果说现在我们现在想新加一个类Cat也实现Animal接口,然后我们调用Cat的方法。代码和Cat类似,区别只是use方法的实现不同,在这里我就不贴了。

   

    可以看到代码直接报错提示不能注入animal,因为有多个Animal type的bean在spring中。为什么会出现这个错误呢,其实就是Autowired是按照by type进行注入的,现在spring要生成一个animal对象,但是在spring容器中存在两个类型的Animal对象,Cat和Dog,这个时候spring就不知道到底该生成哪个对象了。那我们怎么解决这一问题呢,spring给出了两种解决方案。@Primary和@Qualifier。

    1.@Primary修饰Dog类,那么这个时候spring就会优先生成Dog对象赋值给BussionPerssion的animal。@primary我理解就是优先级最高的。但是这个还是存在一个问题,假如Cat类也被@Primary修饰怎么办。为了解决这一问题spring提出了@Qualifier。

    2.@Qualifier代码如下。这两个注解代表什么意思呢?首先@Autowired指定赋值给animal的bean,类型必须是Animal;其次@Qualifier指定该bean的name必须是dog。现在我们通过type,name就可以在spring中唯一确定一个bean赋值给animal了。这个过程可以理解为依赖注入。

@Service
public class BussionPerssion implements Perssion {
    @Autowired
    @Qualifier(value = "dog")
    Animal animal;

    @Override
    public void service() {
        animal.use();
    }
}

      @Resouce

      @Resouce和@Autowired的用法相似,这里只说明注入发现多个bean这种情况,代码如下。@Resource只有一个参数name,在这里显示指定需要name为dog的bean注入。这也就是为什么大家说Resouce是by name注入的。

@Service
public class BussionPerssion implements Perssion {
    @Resource(name = "dog")
    Animal animal;

    @Override
    public void service() {
        animal.use();
    }
}

    这里大家可能会想,如果说Resource是by name的,那么我稍微修改一下Dog代码,让其不在实现Animal,那BussionPerssion 中的animal还会被正常注入吗?答案明显是否定的。

2.Autowired和Resouce的区别。

    在上面的例子中我其实已经提到了两者的区别,在这里总结下。

    @Autowired是按照by type注入,可以配合@Qulifier注解使用,那此时就是by type by name了。

    @Resouce是按照by name注入,如果没有指定name,那么会取属性名称进行注入,如果此时没有找到对应的bean,那么会按照by type注入。如果指定了name那么只会 by name注入。

3.Autowired和Resouce的区别的原因。

    这两个注解的作用都是注入,那么为什么会有这种区别呢?其实我们可以想一下注入的过程其实就是getBean的过程。我们可以看一下源头BeanFactory的getBean方法。

Object getBean(String name) throws BeansException;

<T> T getBean(Class<T> requiredType) throws BeansException;

<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;

Object getBean(String name, Object... args) throws BeansException;

<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

    @Autowired修饰属性时,底层会调用第二个getBean方法,在配合@Qulifier时会调用第三个getBean方法。

    @Resouce修饰属性时,会调用第一个getBean方法,在获取失败时,会调第三个getBean方法。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值