@Autowired、@Resource
我们编写spring 框架的代码时候。一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量。并且要配套写上 get 和 set方法。虽然可以通过eclipse等工具来自动生成。但是还是会引起程序阅读性上的不便。那么既然注解这么强大。是否可以也把他精简掉呢?
当 然可以。这个标签就是@Autowired
Spring 2.5 引入了 @Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
要实现我们要精简程序的目的。需要这样来处理:
* 在applicationContext.xml中加入:
<!-- 该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
* 修改在原来注入spirng容器中的bean的方法。
在域变量上加上标签@Autowired,并且去掉 相应的get 和set方法
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import com.firemax.test.hibernate.AlcorTCitys;
import com.firemax.test.hibernate.AlcorTCitysDAO;
import com.firemax.test.hibernate.AlcorTCountries;
import com.firemax.test.hibernate.AlcorTCountriesDAO;
import com.firemax.test.hibernate.AlcorTProvinces;
import com.firemax.test.hibernate.AlcorTProvincesDAO;
import com.firemax.test.hibernate.AlcotTDistrict;
import com.firemax.test.hibernate.AlcotTDistrictDAO;
public class CountryService {
private static Log logger = LogFactory.getLog(CountryService.class);
@Autowired
private AlcorTCountriesDAO alcorTCountriesDAO;
@Autowired
private AlcorTProvincesDAO alcorTProvincesDAO;
@Autowired
private AlcorTCitysDAO alcorTCitysDAO;
@Autowired
private AlcotTDistrictDAO alcotTDistrictDAO;
public CountryService(){
}
public void updateCountry(AlcorTCountries alcorTCountries ) throws Exception{
this.alcorTCountriesDAO.update(alcorTCountries);
}
....
//这里去掉了哪些DAO 变量的get 和set 方法。
}
* 在applicatonContext.xml中 把原来 引用的<porpery >标签也去掉。
<bean id="CountryService" class="com.firemax.test.service.CountryService">
<property name="alcorTCountriesDAO" ref="AlcorTCountriesDAO" />
<property name="alcorTProvincesDAO" ref="AlcorTProvincesDAO" />
<property name="alcorTCitysDAO" ref="AlcorTCitysDAO" />
<property name="alcotTDistrictDAO" ref="AlcotTDistrictDAO" />
</bean>
修改成
<bean id="CountryService" class="com.firemax.test.service.CountryService">
</bean>
当然,我们也可以在构造函数上使用@Auwowired 注解 。如果构造函数有两个入参,分别是 bean1 和 bean2,@Autowired 将分别寻找和它们类型匹配的 Bean,将它们作为 CountryService (Bean1 bean1 ,Bean2 bean2) 的入参来创建 CountryService Bean。
@Resource
Spring使用@Resource注解完成属性装配
使用Field注入(用于注解方式)
注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员
无法预见最终的装配结果
1.手工装配依赖对象
2.自动装配依赖对象
手工装配依赖对象,这汇总方式中又有两种编程方式
1.在xml配置文件中,通过在bean节点下配置 如
<bean id="personDao" class="com.qn.service.impl.PersonDaoBean"></bean>
<bean id="personService" class="com.qn.service.impl.PersonServiceBean">
<constructor-arg index="0" type="com.qn.dao.PersonDao" ref="personDao"></constructor-arg>
<constructor-arg index="1" value="齐宁"></constructor-arg>
</bean>
2.在java代码中使用@Autowired或@Resource注解方式进行装配,但我们需要在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-2.5.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
</beans>
这个配置隐式注册了多个对注释进行解析处理的处理器:AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessorPersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor
注:@Resource注解在spring安装目录的common-annotations.jar
.在java代码中使用@Autowired或@Resource注解方式进行装配,但我们需要在xml配置文件中配置如下信息
这个配置隐式注册了多个对注释进行解析处理的处理器:AutowiredAnnotationBeanPostProcessor,
CommonAnnotationBeanPostProcessorPersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcesso
r
注:@Resource注解在spring安装目录的common-annotations.jar
在java代码中使用@Autowired或@Resource注解方式进行装配,这两个注解的区别是:@Autowired默认按类型装配。
@Resource默认按名车装配,,当找不到与名称匹配的bean才会按类型装配
@Autowired
用于字段上面
@Autowired
用于属性的setter()方法上
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required的
属性为false。如果想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
@Autowired @Qualifier(“personDaoBean”)
private PersonDao personDao;
@resource注解和@Autowiredyiyang ,也可以标注在字段或属性的setter方法上,但默认的是按名称装配,名称可以通过
@rResource的name属性指定,如果没有指定name属性,当注解标注在字段上面,即默认去字段的名称作为bean名称寻找依
赖对象,当注解标注在属性的setter方法上,即默认取属性的名称作为bean名称寻找依赖对象
@Resource(name=“personDaoBean”)
private PersonDao personDao;//用于字段上
注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时,@Resource注解会回退到按类型装配,但一
旦指定了name属性,就只能按名称装配了
事例
1.定义接口PersonDao
package com.qn.dao;
public interface PersonDao {
void add();
}
2.定义接口PersonService
package com.qn.dao;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public interface PersonService {
void save();
}
3.定义类PersonDaoBean实现PersonDao
package com.qn.service.impl;
import com.qn.dao.PersonDao;
public class PersonDaoBean implements PersonDao{
public void add() {
System.out.println("PersonDaoBean的添加方法");
}
}
4.定义类PersonServiceBean实现PersonService
package com.qn.service.impl;
import javax.annotation.Resource;
import com.qn.dao.PersonDao;
import com.qn.dao.PersonService;
public class PersonServiceBean implements PersonService {
@Resource
private PersonDao personDao;
private String name;
public PersonServiceBean(){}
public PersonServiceBean(PersonDao personDao, String name) {
this.personDao = personDao;
this.name = name;
}
public void save(){
personDao.add();
System.out.println(name);
}
}
5.在bean中进行配置
<?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-2.5.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<bean name="personDao" class="com.qn.service.impl.PersonDaoBean"></bean>
<bean name="personService" class="com.qn.service.impl.PersonServiceBean"></bean>
</beans>
6.在test中进行测试
package com.qn.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.qn.dao.PersonService;
public class test {
public static void main(String []args){
AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
PersonService personService=(PersonService) ctx.getBean("personService");
personService.save();
}
}
结果
这个时候在PersonServiceBean类中
@Resource
private PersonDao personDao;
的注解先是按名称看beans.xml中看是否存在personDao名称如果存在则显示结果
如果beans.xml中没有personDao名字呢?
如下配置
<bean name="personDaoxxxx" class="com.qn.service.impl.PersonDaoBean"></bean>
<bean name="personService" class="com.qn.service.impl.PersonServiceBean"></bean>
结果
这个时候会按类型查找看是否有类型是PersonDao
当然也可以注明name
@Resource(name="personDaoxxxx")
private PersonDao personDao;
结果
也可以把注解写到sett方法上
@Resource
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
结果