@Resource实际使用

作者: 小疯子 分类: Spring 发布时间: 2019-05-15 22:08

一、基本概念了解

spring中什么时候用@Resource,什么时候用@Service。当你需要定义某个业务层的类为一个bean,则在这个类的类名前一行使用@Service("xxx"),就相当于讲这个类定义为一个bean,bean名称为xxx;当需要在某个类中定义一个属性,并且该属性是一个已存在的bean,要为该属性赋值或注入时在该属性上一行使用@Resource(name="xxx"),相当于为该属性注入一个名称为xxx的bean。这里的xxx和上面的xxx是同一个名称。
@Resource装配顺序
  1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配(name和type都需要匹配),找不到则抛出异常
  2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
  3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
  4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配

二、实际使用和结果

(一)代码情况

定义一个接口IFengService,如下所示
r1.png
定义实现此接口的两个实现类,通过@Service来定义bean的名称(后面方便探究不写value的情况下FengServiceImpl1的默认名称,所以代码后期这个类中@Service后面括号就移除了)
r2.png
=================
r3.png

(二)Resource注解注入service类

在另一个类中注入此service,注入的方式尝试了几种

(1)name和type都定义

a. 如果name和type都正常结果肯定是能正常注入的
r4.png
b. name不正常type正常,结果报错如下所示
r5.png
r6.png
c. name正常,type不正常
    * type不正常的方式是:一个完全和定义注入字段类型无关的类型
r7.png
 r8.png
    * type是接口类的一个实现子类,比如是IFengService接口的实现类FengServiceImpl1
         -- name和type指定的是同一个,正常
  r9.png
         -- name和type指定的不一致,报错
r10.png
            r11.png
            Bean named 'com.xds.service.directsale.web.impl.FengServiceImpl1' is expected to be of type 'com.xds.service.directsale.web.impl.FengServiceImpl2' but was actually of type 'com.xds.service.directsale.web.impl.FengServiceImpl1'

(2)只定义name

就很简单啦,获取名称为指定name值的bean;如果name为空或者设置为“”,则会继续按照type类型查找,按照字段定义声明中的类型查找。
如果@Service不定义的话,可能name就是当前被@Service注解的类的名称首字母小写的字符串了。如下代码所写是正常运行的。
r12.png
r13.png

(3)只定义type

找类型匹配的bean,如果匹配了多个或没有则会抛出异常;如果写的是IFengService.class则会匹配两个抛出异常,如果写的是实现类的class比如是FengServiceImpl1.class,会找到唯一的一个类型bean匹配,可以正常运行。

(4)什么都没有指定

复制一下上面的那段话:
如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配
   a. fengService不匹配任何bean的名称,所以会先按byName方式找不到,继续按照IFengService类型查找,结果就是失败的,因为找了两个实现类
 r14.png
 r15.png
   b. fengServiceImpl1是FengServiceImpl1的bean名称,这样子写也是正常运行的,因为先按照byName查直接就查到了
 r16.png
   c. 如果service的bean名称比较复杂,就是我们的FengServiceImpl2类的名称,如下所示
 r17.png
      当注入的时候直接写如下,还是会name找不到,继续byType,继续找到两个继续报错,就算将fengServiceImpl2改成FengServiceImpl2也仍然会报错
 r18.png
      而想要写成这种样子的名字是不可以哒,所以还是通过name属性来指定吧
 r19.png
2+