spring中关于@AutoWired注解&@Resource注解的区别

@AutoWired和@Resource注解的区别

参考网址1:https://blog.csdn.net/weixin_40423597/article/details/80643990

参考网址2:https://www.zhihu.com/question/39356740

两者的基本认识

1、@Autowired注解是Spring自己定义的注解 (Spring团队)

2、Spring框架还去实现了JSR-250(sun/oracle)规范定义的注解@Resource、@PostConstruct以及@PreDestroy。

在某种情况下:Spring实现的@Resource的作用相当于@Autowired

两者的区别

1、只不过@Autowired按byType自动注入、而@Resource默认按 byName自动注入罢了

@Resource

1、@Resource有两个属性是比较重要的,分是name和type,

2、Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,如下

@Resource(name="xxxxServiceImpl")
private UserService userService;

// 源码分析
if(name == 'userServiceImpl'){
    
    
    return beanfacotry.getBean("userServiceImpl")
}

3、而使用type属性时则使用byType自动注入策略。

@Resource(type=UserServiceImpl.class)
private UserService userService;

// 源码分析
if(type == UserServiceImpl.class){
    
    
    return beanfacotry.getBean(UserServiceImpl.class)
}

4、如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。

@Resource //等价于 @Resource(name="xxxxServiceImpl")
private UserService userService;
// 源码分析
if(name == 'userServiceImpl'){
    
    
    return beanfacotry.getBean("userServiceImpl")
}

5、如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常

@Resource(name="xxxx",type=UserServiceImpl.class) 
private UserService userService;

// 源码分析
if(name == 'userServiceImpl' && type == UserServiceImpl.class){
    
    
    return beanfacotry.getBean("userServiceImpl")
}

总结:

1:默认情况 @Resource是根据byname匹配,如果一个接口在开发只有一个实现类,会自动把唯一的实现赋值给接口进行是实例化。这个时候这两者是等价的。
2: 如果@Resource指定的name就必须和sprignioc中的map的key名字要一摸一样。默认情况下,是使用类名首字母小写进行一定,否则报错
3: 如果@Resource指定的type,就必须是当前被注入的类的子类或者当前类,否则报错
4: 如果@Resource指定的type也指定了name,一种双重机制,只有有一个条件不满足就报错。

@Autowired

1、@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。

2、@Autowired:默认按类型装配(这个注解是属业spring的)

@Autowired(type=UserServiceImpl.class)
private UserService userService;

// 源码分析
if(type == UserServiceImpl.class){
    
    
    return beanfacotry.getBean(UserServiceImpl.class)
}

3、默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,

如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:
    
@Autowired(required=false)
private UserService userService;

总结:

1: @Autowired默认是根据bytype来匹配,如果一个接口在开发只有一个实现类,会自动把唯一的实现赋值给接口进行是实例化。这个时候这两者是等价的。
2:@Autowired如果找不到子类,就报错NoBeanDefinitionException异常,如果要解决这个异常,在注解上增加required = false即可,但是这个接口或者类是不会被实例化,也就null
这里这个对象在掉用方法的时候就会出现nullponitexception异常。

猜你喜欢

转载自blog.csdn.net/L_994572281_LYA/article/details/121781173