@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属 性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策 略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Resource装配顺序
1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
下面是代码:在读配置文件中,由于不同的方法是在一起进行测试的,在看的时候,需要对应相应的顺序。先看所有的配置文件,可以有一个基本的印象。
测试时使用的所有的配置文件application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- 时@Autowrite自动生效 -->
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<!--使得@Resource生效 -->
<bean
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<!-- -使得@Qualifier生效 -->
<context:annotation-config />
<context:property-placeholder
location="classpath:/com/test/service3/testvalue.properties" />
<!-- 将jdbcTemplate对象注入到userService中 -->
<bean id="userDao" class="com.test.UserDao">
<property name="name" value="sss" />
</bean>
<bean id="userDao1" class="com.test.UserDao">
<property name="name" value="aaa" />
</bean>
<bean id="userDao2" class="com.test.UserDao">
<property name="name" value="bbb" />
</bean>
<bean id="userDao4" class="com.test.UserDao">
<qualifier type="com.test.service2.MyQualify" value="userMy" />
<property name="name" value="auto_qualifier" />
</bean>
<bean id="user1" class="com.test.service.UserService1" />
<bean id="user2" class="com.test.service.UserService2" />
<bean id="user3" class="com.test.service.UserService3" />
<bean id="user4" class="com.test.service2.UserService_1" />
<bean id="test_value" class="com.test.service3.TestValue"/>
<!-- <bean id="userDao1" class="com.test.service3.UserDao"> -->
<!-- <qualifier type="com.test.service3.MyQualify" value="userMy" /> -->
<!-- <property name="name" value="aaa" /> -->
<!-- </bean> -->
<!-- <bean id="u2" class="com.test.service3.UserService2" /> -->
</beans>
在写java代码之前
在测试的时候,模拟了一个UserDao的类,它并不是一个真正的和数据库相关的到类,仅仅是为了验证其中的一些关系和方法。
1 测试单独使用@AutoWrite注解,
实例代码:
package com.test.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import com.test.UserDao;
public class UserService1 {
// 可以标注在字段上,构造方法上,setXXX 3种方式是等效的
@Autowired
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public UserService1(UserDao userDao) {
super();
this.userDao = userDao;
}
}
测试代码
public void test_autoWrite(){
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
"ApplicationContext.xml");
UserService1 user = (UserService1)ctx.getBean("user1");
System.out.println(user.getUserDao().getName());
}
会读取user1 对应的实体类,在该类中注入了一个UserDao的实例变量。当运行实例的时候,会答应出 sss,从结果可以看出,在userService1中,UserDao 类的实例userDao,引入的实例变量时配置文件中id=userDao的实例。
2 @autowrite 与@qualifier 结合使用
当一个类,有多一个实例变量时,可以通过@qualifier注解指定应用的是哪一个实例变量
代码如下:
package com.test.service;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.test.UserDao;
public class UserService2 {
@Autowired
@Qualifier("userDao1")
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
测试代码如下:
public void test_qualifier(){
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
"ApplicationContext.xml");
UserService3 user = (UserService3)ctx.getBean("user3");
System.out.println(user.getUserDao().getName());
}
程序会输入aaa 的结果,则userDao引入的实例变量是配置文件中userDao1对应的实例变量。