一、通過之前學習知道注入依賴對象有:手工裝配和自動裝配。
手工裝配又有兩種裝配方式:
(1)、在XML 配置文件中,通過 bean 節點配置,如下:
<bean id="personService" class="com.learn.service.impl.PresonServiceImpl">
<property name="presonDao" ref="XXX"></property>
<constructor-arg index="1" value="XXX"></constructor-arg>
</bean>
(2)、在java 代碼中使用@Autowired 或者 @Resource 注解方式進行裝配,但是需要在xml 配置文件中配置一下信息:
<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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
這個配置隱式注冊了多個對注釋進行解析出來的處理器:
AutowiredAnnotationBeanPostProcessor 、CommonAnnotationBeanPostProcessor
PersistenceAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor
其實,注解本身做不了任何事情,和XML一樣,只起到配置的作用,主要在於背后強大的處理器 。
另外,比較建議使用@Resource注解,而不要使用@Autowired注解。因為@Autowired注解是Spring提供的,而@Resource注解是J2EE提供的 ,在JDK6中就已經包含@Resource注解了,所以它沒有跟Spring緊密耦合,並且在使用Spring時,若使用了JSR-250中的注解,如@Resource//@PostConstruct//@PreDestroy ,那么還需要Spring安裝目錄中的SPRING_HOME\\lib\\j2ee\\common-annotations.jar包的支持,這里面的@Resource注解就是在SPRING_HOME\\lib\\j2ee\\common-annotations.jar中的 。
@Resource注解
@Resource注解和@Autowired一樣,也可以標注在字段或屬性的setter方法上
@Resource默認按名稱裝配,名稱可以通過name屬性指定。當找不到與名稱匹配的bean時,才會按類型裝配
若注解標注在字段上且未指定name屬性,則默認取字段名作為bean名稱尋找依賴對象
若注解標注在setter上且未指定name屬性,則默認取屬性名作為bean名稱尋找依賴對象
如果沒有指定name屬性,並且按照默認的名稱仍找不到依賴對象時,它就會按類型匹配
但只要指定了name屬性,就只能按名稱裝配了
@Autowired注解
@Autowired默認是按類型裝配對象的,默認情況下它要求依賴對象必須存在
如果允許null值,可以設置它的required屬性為FALSE,如@Autowired(required=false)
若想要按名稱裝配,可以結合@Qualifier注解一起使用,如@Autowired(required=false) @Qualifier("personDaoBean")
二、學習用注解的方式裝配:
1、導入common-annotations.jar 包,下載地址:http://www.java2s.com/Code/Jar/c/Downloadcommonannotationsjar.htm
2、在 java代碼中使用@Resource注解 或@Autowired注解方式進行裝配,它們的區別是:
@Autowired默認是按類型裝配對象的,@Resource默認按名稱裝配,當找不到與名稱匹配的bean才會按類型專配。
@Autowired
private PersonDao personDao;//用於字段上
@Autowired
public void setOrderDao(OrderDao orderDao) {//用於屬性的setter方法上
this.orderDao = orderDao;
}
@Autowired注解是按類型裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許null值,可以設置它required屬性為false。如果我們想使用按名稱裝配,可以結合 @Qualifier 注解一起使用。如下:
@Autowired @Qualifier("personDaoBean")
private PersonDao personDao;
@Resource注解和 @Autowired一樣,也可以標注在字段或屬性的setter方法上,但它默認按名稱裝配。名稱可以通過 @Resource的name屬性指定,如果沒有指定name屬性,當注解標注在字段上,即默認取字段的名稱作為bean名稱尋找依賴對象,當注解標注在屬性的setter方法上,即默認取屬性名作為bean名稱尋找依賴對象。
@Resource(name=“personDaoBean”)
private PersonDao personDao;//用於字段上
注意:如果沒有指定name屬性,並且按照默認的名稱仍然找不到依賴對象時, @Resource注解會回退到按類型裝配。但一旦指定了name屬性,就只能按名稱裝配了。
3、實例, PresonServiceImpl 類,代碼如下:
package com.learn.service.impl;
import javax.annotation.Resource;
import com.learn.dao.PresonDao;
import com.learn.service.PresonService;
/**
* 業務層
* @author Administrator
*
*/
public class PresonServiceImpl implements PresonService {
@Resource private PresonDao presonDao;
private String name;
public PresonServiceImpl(){
}
public PresonServiceImpl(PresonDao presonDao, String name) {
this.presonDao = presonDao;
this.name = name;
}
/* (non-Javadoc)
* @see com.learn.service.impl.PresonService#save()
*/
@Override
public void save(){
presonDao.add();
}
}
通過上面講解知道,@Resource注解方式默認按名稱裝配,所以會取字段的名稱 presonDao 作為bean名稱尋找依賴對象 。(上面的 PresonDao 接口和所對應的類,在之前有講過)
4、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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean id="personDao" class="com.learn.dao.impl.PresonDaoImpl"></bean>
<bean id="personService" class="com.learn.service.impl.PresonServiceImpl"></bean>
</beans>
5、單元測試:
package junit.test;
import static org.junit.Assert.*;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.learn.service.PresonService;
public class TestSpring {
@Test
public void initContainerSpring() {
//實例化spring容器 (使用類構造器實例化)
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("com//learn//spring//learn1.xml");
PresonService personService = (PresonService)ctx.getBean("personService");
personService.save();
}
}
如果我們將 xml 中 id=“personDao” 改為 id=“person” ,那么通過@Resource注解是找不到以字段 presonDao 作為 bean 名稱的依賴對象,這是會按類型裝配,即@Autowired 注解。當然也可以明確的指定 name 屬性,即
@Resource(name="preson") private PresonDao presonDao;
一旦指定了name屬性,就只能按名稱裝配。所以會去找到 xml 文件中 id=“preson” 的 bean。
6、也可以使用屬性的setter 方法, 修改 PresonServiceImpl 類,代碼如下:
package com.learn.service.impl;
import javax.annotation.Resource;
import com.learn.dao.PresonDao;
import com.learn.service.PresonService;
/** * 業務層 * @author Administrator * */
public class PresonServiceImpl implements PresonService {
private PresonDao presonDao;
private String name;
public PresonServiceImpl(){
}
public PresonServiceImpl(PresonDao presonDao, String name) {
this.presonDao = presonDao;
this.name = name;
}
@Resource
public void setPresonDao(PresonDao presonDao) {
this.presonDao = presonDao;
}
/* (non-Javadoc) * @see com.learn.service.impl.PresonService#save() */
@Override
public void save(){
//System.out.println("name="+name);
presonDao.add();
}
}
@Resource注解和@Autowired一樣,也可以標注在字段或屬性的setter方法上,但它默認按名稱裝配。當注解標注在屬性的setter方法上,即默認取屬性名作為bean名稱尋找依賴對象。