@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它是J2EE的,它的包是javax.annotation.Resource,而@Autowired的包是org.springframework.beans.factory.annotation.Autowired,但Spring支持该注解的注入(Spring支持几个JSR-250规范定义的注解,它们分别是@Resource、@PostConstruct、@PreDestroy)。
/*************** @Autowired源码 ***************/
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* Defaults to {@code true}.
*/
boolean required() default true;
}
/*************** @Resource源码 ***************/
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
//两个重要属性:name和type
String name() default "";
String lookup() default "";
Class type() default java.lang.Object.class;
/**
* The two possible authentication types for a resource.
*/
enum AuthenticationType {
CONTAINER,
APPLICATION
}
AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
boolean shareable() default true;
String mappedName() default "";
String description() default "";
}
public class TestServiceImpl {
// 下面两种@Autowired只要使用一种即可
@Autowired
private UserDao userDao; // 用于字段上
@Autowired
public void setUserDao(UserDao userDao) { // 用于属性的方法上
this.userDao = userDao;
}
}
2.不同点
(1)@Autowired只按照byType注入。默认情况下要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false。如:@Autowired(required=false),如果我们想使用byName注入,可以结合@Qualifier注解进行使用,如下:
@Autowired(required=false)
@Qualifier("userDao")
private UserDao userDao;
(2)@Resource默认按照byName自动注入,有两个重要属性:name和type。Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用那么属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略,如果既不指定name也不指定type属性,这是将通过反射机制使用byName自动注入。
public class TestServiceImpl {
// 下面两种@Resource只要使用一种即可
@Resource(name="userDao")
private UserDao userDao; // 用于字段上
@Resource(name="userDao",type=UserDao.class)
public void setUserDao(UserDao userDao) { // 用于属性的setter方法上
this.userDao = userDao;
}
}
@Resource装配顺序:
id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
这个方法的优点在于间接层带来了巨大的部署弹性。比如说,一个单独的系统测试环境应该不再需要JNDI注册。在这种情况下,在系统测试配置中可以提供如下的bean定义:
"dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" />
顺便提一下,上面的例子中,实际的JDBC连接属性从一个属性文件(properties file)解析而来,在这个属性文件里,关键字与提供的${占位符}互相对应,这需要注册一个名为PropertyPlaceholderConfigurer的BeanFactoryPostProcessor实现来完成。这是具体化那些属性(通常是针对特定环境的属性)常用的技术,这些属性可能比其他配置修改得更为频繁。
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
bean>
Srping2.5中新加入了‘context’命名空间,这个命名空间让我们能够得到更为简洁的方式来实现属性占位符(property placeholder)的配置:
<context:property-placeholder location="classpath:jdbc.properties"/>
@Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入