手工注入扩展:http://blessht.iteye.com/blog/1162131
前言:自己在复习spring相关知识,特此记录,欢迎大家交流指正-----QQ:767872620
一、手工装配
1.在xml配置文件中,通过bean节点配置
(1)构造器式注入:
<!--constructor-arg使用构造器注入,index为构造器参数索引,明确定义构造函数 -->
<constructor-arg index="0" ref="PersonDaoBean"/>
<constructor-arg index="1" value="要西"/>
(2)属性setter方法式注入:
<bean id="PersonServiceref" class="cn.itcast.service.imp.PersonServiceBeanref">
<property name="persondao" >
<bean id="PersonDaoBean" class="cn.itcast.dao.imp.PersonDaoBean"></bean>
</property>
<property name="name" value="张鑫"></property>
<property name="id" value="88"></property>
<property name="age" value="18"></property>
</bean>
对于集合属性的注入:
<bean id="PeersonCollectionBean" class="cn.itcast.service.imp.PeersonCollectionBean">
<!--constructor-arg使用构造器注入,index为构造器参数索引,明确定义构造函数 -->
<!--<constructor-arg index="0" ref="PersonDaoBean"/>-->
<!--<constructor-arg index="1" value="要西"/> -->
<property name="sets">
<set>
<value>第一个set值</value>
<value>第二个set值</value>
<value>第三个set值</value>
</set>
</property>
<property name="lists">
<list>
<value>第一个list值</value>
<value>第二个list值</value>
<value>第三个list值</value>
</list>
</property>
<property name="properties">
<props>
<prop key="key1">第一个properties值</prop>
<prop key="key2">第二个properties值</prop>
<prop key="key3">第三个properties值</prop>
</props>
</property>
<property name="maps">
<map>
<entry key="key1" value="第一个map值"></entry>
<entry key="key2" value="第二个map值"></entry>
<entry key="key3" value="第三个map值"></entry>
</map>
</property>
</bean>
public class PeersonCollectionBean implements PersonCollects {
/**
* (1)构造器注入
*/
/**
* (2)注解注入
* 1.用在属性上
* @Resource 在没有指定name属性是默认按照名称装配(配置文件中的id),不行按照类装配
*
* @Resource(name=" ") 只能按照名称装配,没找到给以null,报错
*
*/
@ItcastResource //自定义注解
//@Resource
public PersonDao persondao;
public String name;
/**
* set方法集合属性注入
*/
public Set<String> sets = new HashSet<String>();
/**
* 注解使用在setter方法上,用setter方式注入
* @param persondao
*/
public void setPersondao(PersonDao persondao) {
this.persondao = persondao;
}
/**
* 使用构造器注入,必须明确定义一个构造器
* 此时配置文件中必须包含constructor-arg标签
*/
/* public PeersonCollectionBean(PersonDao persondao, String name) {
super();
this.persondao = persondao;
this.name = name;
}
*/
public List<String> lists = new ArrayList<String>();
public Properties properties = new Properties();
public Map<String,Object>maps = new HashMap<String,Object>();
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void setLists(List<String> lists) {
this.lists = lists;
}
public List<String> getLists() {
return lists;
}
public Set<String> getSets() {
return sets;
}
public void setSets(Set<String> sets) {
this.sets = sets;
}
public void Save(){
this.persondao.add();
System.out.println(this.name);
}
测试:
ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
PersonCollects pcs =(PersonCollects) cxt.getBean("PeersonCollectionBeannew");
*//**
* set方法注入
*//*
System.out.println("**************set集合注入*****************");
for(String value:pcs.getSets()){
System.out.println(value);
}
System.out.println("**************list集合注入*****************");
for(String value:pcs.getLists()){
System.out.println(value);
}
System.out.println("**************properties集合注入*****************");
for(Object value:pcs.getProperties().keySet()){
System.out.println(pcs.getProperties().getProperty((String)value));
}
System.out.println("**************maps集合注入*****************");
for(String key:pcs.getMaps().keySet()){
System.out.println(pcs.getMaps().get((String)key));
}
*//**
* 构造器注入
*//*
System.out.println("**************构造方法注入*****************");
pcs.Save();
*/
/*ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext2.xml");
PersonCollects pcs =(PersonCollects) cxt.getBean("PeersonCollectionBean");
(3)使用内部bean注入
<!--2.使用内部bean注入,此bean不能用于其他bean -->
<!-- <bean id="PersonServiceref" class="cn.itcast.service.imp.PersonServiceBeanref">
<property name="persondao" >
<bean id="PersonDaoBean" class="cn.itcast.dao.imp.PersonDaoBean"></bean>
</property>
<property name="name" value="张鑫"></property>
<property name="id" value="88"></property>
<property name="age" value="18"></property>
</bean>
缺点:bean多时,xml冗长
2.使用Field注入(用于注解方式)
配置文件导入:
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation中导入:
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
说明:
bean节点下的:
<!-- 注解注入 -->
<context:annotation-config/>
这个配置隐式注册了多个对注释进行解析处理的处理器:AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,
RequestAnnotationBeanPostProcessor
注:@Resource注解在spring安装目录的lib\j2ee\common-annotations.jar
@Autowired与@Resoure注解
在java代码中使用@Autowired或是@Resource注解方式进行装配
1.@Autowired默认按类型装配
(1)用于类属性上
@Autowired
public PersonDao persondao;
(2)用于setter方法上
@Autowired
public void setPersondao(PersonDao persondao) {this.persondao = persondao;}
说明:
@Autowired注解是按照类型装配依赖对象。
默认情况下他要求依赖对象必须存在,如果允许为null值,可以设置它的required属性为false。
如果我们想使用按字段名称装配,可以结合@Qualifier注解一起使用
@Autowired@Qualifier("PersonDaoBean")
public void setPersondao(PersonDao persondao) {this.persondao = persondao;}
2.@Resource:默认按名称装配,当找不到与名称匹配的bean才会按照类类型装配。
.@Resource和@Autowired一样,也可以标注在字段或是属性的setter方法上,但他默认按照名称装配。
名称可以通过@Resource的name属性指定。如果没有指定name属性,当注解标注在字段上,即默认取字段的名称,作为bean名称寻找依赖对象;当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
@Resource(name="PersonDaoBean") //@Resource
public PersonDao persondao;
@Resource(name="PersonDaoBean") //@Resource
public void setPersondao(PersonDao persondao) {this.persondao = persondao;}
注意:
如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时,@Resource注解会回退到按照类型装配。但一旦指定了name属性,就只能按照名称装配。
二、自动装配 不推荐使用
如:
<bean id=" " class=" " autowire=“byType”/>
autowire属性:
(1)byType:按类型装配,可以根据属性的类型,在容器中寻找跟该类型匹配的bean。如果发现多个,那么将会抛出异常。如果没有找到,即属性值为null。
(2)byName:按名称装配,可以根据属性的名称,在容器中寻找跟该名称匹配的bean。如果没有找到,即属性值为null。
(3)constructon与byType的方式类似,不同之处在于它应用与构造器参数,如果在容器中没有找到与构造器参数类型一致的bean,那么将抛出异常。
(4)autodetect:通过bean类的自省机制(introspection)来决定是使用constructon还是使用byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。
建议:
自动装配:开发人员将无法预见最终的装配结果。