@Resource(这个注解属于J2EE的,JSR250),默认安照名称进行装配,名称可以通过name属性进行指定, 如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
@Resource注解的源码如下所示。
package javax.annotation; import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.*; @Target({TYPE, FIELD, METHOD}) @Retention(RUNTIME) public @interface Resource { String name() default ""; String lookup() default ""; Class<?> type() default java.lang.Object.class; enum AuthenticationType { CONTAINER, APPLICATION } AuthenticationType authenticationType() default AuthenticationType.CONTAINER; boolean shareable() default true; String mappedName() default ""; String description() default ""; }
@Inject注解
@Inject注解(JSR330)默认是根据参数名去寻找bean注入,支持spring的@Primary注解优先注入,@Inject注解可以增加@Named注解指定注入的bean。
@Inject注解的源码如下所示。
package javax.inject; import java.lang.annotation.Target; import java.lang.annotation.Retention; import java.lang.annotation.Documented; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.CONSTRUCTOR; import static java.lang.annotation.ElementType.FIELD; @Target({ METHOD, CONSTRUCTOR, FIELD }) @Retention(RUNTIME) @Documented public @interface Inject {}
注意:要想使用@Inject注解,需要在项目的pom.xml文件中添加如下依赖。
<dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>
项目案例
测试@Resource注解
首先,我们将项目中的PersonService类标注在personDao字段上的@Autowired注解和@Qualifier注解注释掉,然后添加@Resource注解,如下所示。
//@Qualifier("personDao") //@Autowired(required = false) @Resource private PersonDao personDao;
接下来,我们运行AutowiredTest类的testAutowired01()方法,输出的结果信息如下所示。
PersonService{personDao=PersonDao{remark='1'}}
可以看到,使用@Resource注解也能够自动装配组件,只不过此时自动装配的是remark为1的personDao。而不是我们在AutowiredConfig类中配置的优先装配的remark为2的personDao。AutowiredConfig类中配置的remark为2的personDao如下所示。
@Primary @Bean("personDao2") public PersonDao personDao(){ PersonDao personDao = new PersonDao(); personDao.setRemark("2"); return personDao; }
我们在使用@Resource注解时,可以通过@Resource注解的name属性显示指定要装配的组件的名称。例如,我们要想装配remark为2的personDao,只需要为@Resource注解添加 name="personDao2"
属性即可。如下所示。
//@Qualifier("personDao") //@Autowired(required = false) @Resource(name = "personDao2") private PersonDao personDao;
接下来,我们再次运行AutowiredTest类的testAutowired01()方法,输出的结果信息如下所示。
PersonService{personDao=PersonDao{remark='2'}}
可以看到,此时输出了remark为2的personDao,说明@Resource注解可以通过name属性显示指定要装配的bean。
测试@Inject注解
在PersonService类中,将@Resource注解注释掉,添加@Inject注解,如下所示。
//@Qualifier("personDao") //@Autowired(required = false) //@Resource(name = "personDao2") @Inject private PersonDao personDao;
修改完毕后,我们运行AutowiredTest类的testAutowired01()方法,输出的结果信息如下所示。
PersonService{personDao=PersonDao{remark='2'}}
可以看到,使用@Inject注解默认输出的是remark为2的personDao。这是因为@Inject注解和@Autowired注解一样,默认优先装配使用了@Primary注解标注的组件。
@Resource和@Inject注解与@Autowired注解的区别
不同点
- @Autowired是spring专有注解,@Resource是java中JSR250中的规范,@Inject是java中JSR330中的规范
- @Autowired支持参数required=false,@Resource,@Inject都不支持
- @Autowired,和@Inject支持@Primary注解优先注入,@Resource不支持
- @Autowired通过@Qualifier指定注入特定bean,@Resource可以通过参数name指定注入bean,@Inject需要@Named注解指定注入bean
相同点
三种注解都可以实现bean的注入。