java程序员的从0到1:@Resource与@Autowired的比较
目录:
1.@Resource与@Autowired的源码分析
2.@Resource与@Autowired的相同点
3.@Resource与@Autowired的不同点
正文:
1.@Resource与@Autowired的源码分析
想要跟加深入的了解到这两个注解的不同,还要从他们的源码入手,首先来看看它们底层的源码实现:
@Autowired的源码
1 @Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 public @interface Autowired { 5 boolean required() default true; 6 }
@Autowired的实例
@Controller public class HappyController { @Autowired //默认依赖的ClubDao 对象(Bean)必须存在 //@Autowired(required = false) 改变默认方式 @Qualifier("goodClubService") private ClubService clubService; // Control the people entering the Club // do something }
@Resource的源码
@Target({TYPE, FIELD, METHOD}) @Retention(RUNTIME) public @interface Resource { String name() default ""; String lookup() default ""; Class<?> type() default java.lang.Object.class; ... }
@Resource的实例
public class AnotationExp { @Resource(name = "HappyClient") private HappyClient happyClient; @Resource(type = HappyPlayAno .class) private HappyPlayAno happyPlayAno; }
其中@AutoWired这个注解类中只有一个注解属性:required,这个注解属性代表了注入Bean的默认方式,如果不明确指定,其值为true。还要说明一下的是这个@AutoWired注解是Spring中的。
而@Resource这个注解是JDK中的,它的注解属性有很多:name、lookup、type,这些注解属性的具体含义如下:
源代码注解 | 翻译后 | |
name |
The JNDI name of the resource. For field annotations, |
资源的JNDI名称(对于属性而言) |
lookup |
The name of the resource that the reference points to. It can |
引用指向的资源的名称。它可以 |
type |
The Java type of the resource. For field annotations, |
资源的Java类型。字段注释, |
其中比较常用的是name和type属性,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
2.@Resource与@Autowired的相同点
@Resource的作用相当于@Autowired,均可标注在字段或属性的setter方法上。
3.@Resource与@Autowired的不同点
@AutoWired | @Resource | |
出处 | Spring的注解 | javax.annotation注解,而是来自于JSR-250,J2EE提供,需要JDK1.6及以上。 |
注入方式 | 只按照Type 注入 | 默认按Name自动注入,也提供按照Type 注入 |
属性 | @Autowired注解可用于为类的属性、构造器、方法进行注值。默认情况下,其依赖的对象必须存在(bean可用),如果需要改变这种默认方式,可以设置其required属性为false。 还有一个比较重要的点就是,@Autowired注解默认按照类型装配,如果容器中包含多个同一类型的Bean,那么启动容器时会报找不到指定类型bean的异常,解决办法是结合@Qualified注解进行限定,指定注入的bean名称。 |
@Resource有两个中重要的属性:name和type。name属性指定byName,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。 需要注意的是,@Resource如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。 |
注:@Resource注解的使用性更为灵活,可指定名称,也可以指定类型 ;@Autowired注解进行装配容易抛出异常,特别是装配的bean类型有多个的时候,而解决的办法是需要在增加@Qualitied进行限定。