@Autowired 和 @Resource 详解

前言

Spring中,@Resource和@Autowired都是做bean的注入时使用。使用过程中,有时候@Resource 和 @Autowired可以替换使用;有时,则不可以。

下面,根据自己的学习,整理下这两个注解使用中的共同点和不同点,及用法上的不同。

共同点

@Resource和@Autowired都可以作为注入属性的修饰,在接口仅有单一实现类时,两个注解的修饰效果相同,可以互相替换,不影响使用。都可以用来装配bean,都可以写在字段上,或者方法上。

不同点

@Autowired

@Autowird 属于spring框架,默认使用类型(byType)进行注入,例如下面代码:

@Autowired   
private Human human;

系统会根据接口进行注入,如果这个接口只有一个实现类,那么会正常注入,如果没有实现类,它就会报错,我们可以做如下处理:如果找不到对应的bean时候,不会抛出错误,如果required = true,当不存在bean时候,就会抛出异常。

@Autowired(required = false)   
private Human human;

如果Human不止一个实现类,那么它也会报错,

1.对此要配合@Qualifier 使用,这样自动注入的策略就从 byType 转变成 byName .如下面代码:

@Autowired   
@Qualifier("man")   
public Human hunam;  
或者
@Autowired   
public void setUser(@Qualifier("man") Human human) {   
    ...
} 

这样spring会根据@Qualifier指定的id进行注入(依据ID查询对应的bean).

2.还有一种解决方法是在其中一个实现类中 添加 @Primary 注解,这样在有多个实现bean时,优先注入被@Primary注解修饰的那个。

@Service
@Primary
public class Man implements Human {
 
	public String runMarathon() {
		return "A man run marathon";
	}
}

@Resource

@Resource是JavaEE自带的注解,根据ID进行注入的。@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按byName自动注入罢了。

@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。

@Resource装配顺序

  • 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
  • 如果仅仅指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
  • 如果仅仅指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
  • 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配.

推荐使用

@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。这样代码看起就比较优雅。

你可能感兴趣的:(笔记,spring,java-ee)