Annotation注解的注入方式
- 准备工作
1) 引入依赖包
将下列依赖包加入项目的classpath中:
%SPRING_DEP%/javax.annotation/com.springsource.javax.annotation/1.0.0/com.springsource.javax.annotation-1.0.0.jar
%SPRING_DEP%的路径参考http://wangxiangblog.blogspot.com/2010/10/spring-v302-learning-note-2-sample.html
2) 在Java代码中使用@Autowire和@Resource注解的方式,需要context命名空间的支持
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd ">
<context:annotation-config />
</beans>
<context:annotation-config /> 这个配置隐式注册了多个对annotation进行解析的处理器,如
AutowireAnnotationBeanPostProcessor,
CommonAnnotationBeanPostProcessor,
PersistenceAnnotationBeanPostProcessor,
RequiredAnnotationBeanPostProcessor等。
- @Autowired & @Resource
在Java代码中使用@Autowired和@Resource注解的方式进行装配,二者的区别:
推荐采用@Resource注解的方式指定依赖对象,为J2EE的一部分,不是专属于Spring框架
使用方法:
@Autowired
private PersonDao personDao; // 用于字段上
@Autowired
public void setPersonDao (PersonDao personDao) { // 用于属性的setter方法上
this.personDao = personDao;
}
@Autowired注解是按类型装配依赖对象,默认情况下要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。 如果想使用按名称装配,可以结合@Qualifier注解一起使用,如:
@Autowired @Qualifier("personDao")
private PersonDao personDao;
@Resource注解和@Autowired注解一样,也可以标注在字段或者属性的setter方法上,它默认按照名称装配,名称也可以通过@Resource的name属性指定。
如果没有name属性,当标注在字段上时,默认取字段名作为bean名称寻找依赖对象;当标注在属性的setter方法上,默认取属性名作为bean名称寻找依赖对象
@Resource(name="personDao")
private PersonDao personDao; // 用于字段上
- 验证
package com.spring.test.dao;
public class PersonDao {
public void add() {
System.out.println("This is add() method in DAO layer.");
}
}
-------------------------------------------------------------------------------
package com.spring.test.manager.impl;
import javax.annotation.Resource;
import com.spring.test.dao.PersonDao;
import com.spring.test.manager.IPersonService;
public class PersonManager implements IPersonService {
@Resource
private PersonDao personDao; //应用在类的属性上
private String name;
public PersonManager() {
}
@Override
public void save() {
personDao.add();
System.out.println("name is " + name);
}
public void setName(String name) {
this.name = name;
}
}
-------------------------------------------------------------------------
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<bean id="personDao" class="com.spring.test.dao.PersonDao" />
<bean id="personService" class="com.spring.test.manager.impl.PersonManager">
<property name="name" value="CCC" />
</bean>
</beans>
----------------------------------------------------------------------------
package com.spring.test.junit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.test.manager.IPersonService;
public class PersonServiceTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Test
public void test() {
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");
IPersonService personService = (IPersonService) ctx
.getBean("personService");
personService.save();
}
}
运行该测试用例,可在控制台看到如下结果:
This is add() method in DAO layer.
name is CCC
说明注入对象成功。
@Resource
private PersonDao personDao;
spring会根据字段名personDao到配置文件中找到id/name为personDao的bean,如果可以找到,则注入到PersonManager中。如果我们修改配置这个bean ID为"personDaoXXX",
<bean id="personDaoXXX" class="com.spring.test.dao.PersonDao" />
再次运行测试用例,发现仍能得到正确结果,因为@Resource先按名称匹配,如果没有匹配到,就按照类型匹配,发现类型为com.spring.test.dao.PersonDao,就自动找到并注入。
当然也可以明确指定名称
@Resource(name="personDaoXXX")
private PersonDao personDao;
运行测试用例,可能得到正确结果。
package com.spring.test.manager.impl;
import javax.annotation.Resource;
import com.spring.test.dao.PersonDao;
import com.spring.test.manager.IPersonService;
public class PersonManager implements IPersonService {
private PersonDao personDao;
private String name;
public PersonManager() {
}
@Resource
public void setPersonDao(PersonDao personDao) { //应用在属性的setter方法上也可以
this.personDao = personDao;
}
@Override
public void save() {
personDao.add();
System.out.println("name is " + name);
}
public void setName(String name) {
this.name = name;
}
}