SpringFrameworkSpring 开发程序员

@Autowired @Resource @Inject 区别简

2018-04-27  本文已影响230人  殷天文
先看例1
// 一个接口
public interface IOCService {
}
// 接口实现
@Service
public class IOCServiceImpl0 implements IOCService {
}
// 控制层
@Controller
public class TController {

    @Autowired private IOCService iOCService0;
    
    @Inject private IOCService iOCService01;
    
    @Resource private IOCService iOCService011;
    
    @RequestMapping("/t")
    @ResponseBody
    public void t() {
        System.out.println(iOCService0);
        System.out.println(iOCService01);
        System.out.println(iOCService011);
    }   
}

打印结果


  1. @Inject 与 @Autowired : 在Spring的环境下,@Inject 和 @Autowired是相同的,@Inject是 jsr-330 定义的规范,@Autowired 为 Spring 注解,二者默认都是 byType 策略进行注入。即 Spring会直接将 IOCService 类型的唯一 一个bean赋值给 iOCService0 这个成员变量
  2. @Resource :会先采用 byName 策略进行注入,如果byName 无法找到 会使用 byType 策略,如上述例子中。我们没有指定 name ,@Resource byName 无法找到bean,他会使用byType 策略进行注入。
例2

这个时候,我们为 IOCService 接口 增加一个实现类

@Service
public class IOCServiceImpl1 implements IOCService {
}

重启项目,这个时候 注入抛出异常,因为 当使用 byType 策略注入的时候 Spring 注入的接口所对应的bean 必须是唯一的,当有两个实现类的时候 Spring会找到 IOCService 的两个实例。

nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type 'com.wansidong.communicate.test.IOCService' available: 
expected single matching bean but found 2: IOCServiceImpl0,IOCServiceImpl1

这时候需要使用 byName 策略进行注入

@Controller
public class TController {

    @Autowired
    @Qualifier("IOCServiceImpl0")
    private IOCService iOCService0;
    
    @Inject
    @Qualifier("IOCServiceImpl0")
    private IOCService iOCService00;
    
    @Resource(name="IOCServiceImpl0")
    private IOCService iOCService000;
    
    @Autowired
    @Qualifier("IOCServiceImpl1")
    private IOCService iOCService1;
    
    @Inject
    @Named("IOCServiceImpl1")
    private IOCService iOCService11;
    
    @Resource(name="IOCServiceImpl1")
    private IOCService iOCService111;
    
    @RequestMapping("/t")
    @ResponseBody
    public void t() {
        System.out.println("--------------------注入 IOCServiceImpl0");
        System.out.println(iOCService0);
        System.out.println(iOCService00);
        System.out.println(iOCService000);
        System.out.println("--------------------注入 IOCServiceImpl1");
        System.out.println(iOCService1);
        System.out.println(iOCService11);
        System.out.println(iOCService111);
    }
    
}

打印结果如下


  1. @Qualifier 与 @Named :可以看到 这两个注解配合 @Autowired 和 @Inject 都可以实现 byName 方式注入
  2. @Resource : 通过设置 @Resource(name="xxx") 完成 byName 注入

疑问:
写到这儿的时候,我发现一个问题,如果哪位知道的朋友,看到了可以私信,评论告诉我。
我记得之前 我看过 Spring 通过@Controller @Service 创建的bean name 默认是首字母小写的类名,但是我这里抛出的 异常打印 bean 名称 是大写,而且我在指定 name 的时候 首字母小写也会报错,说明 Spring 为我创建的 bean 和 类名相同 ,为什么呢?

对于 Spring 深层次的理解还是不够, 如果文章中哪里说的不对,还望各位看官指出。

上一篇下一篇

猜你喜欢

热点阅读