@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);
}
}
打印结果
- @Inject 与 @Autowired : 在Spring的环境下,@Inject 和 @Autowired是相同的,@Inject是 jsr-330 定义的规范,@Autowired 为 Spring 注解,二者默认都是 byType 策略进行注入。即 Spring会直接将 IOCService 类型的唯一 一个bean赋值给 iOCService0 这个成员变量
- @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);
}
}
打印结果如下
- @Qualifier 与 @Named :可以看到 这两个注解配合 @Autowired 和 @Inject 都可以实现 byName 方式注入
- @Resource : 通过设置 @Resource(name="xxx") 完成 byName 注入
疑问:
写到这儿的时候,我发现一个问题,如果哪位知道的朋友,看到了可以私信,评论告诉我。
我记得之前 我看过 Spring 通过@Controller @Service 创建的bean name 默认是首字母小写的类名,但是我这里抛出的 异常打印 bean 名称 是大写,而且我在指定 name 的时候 首字母小写也会报错,说明 Spring 为我创建的 bean 和 类名相同 ,为什么呢?
对于 Spring 深层次的理解还是不够, 如果文章中哪里说的不对,还望各位看官指出。