Spring中属性注入详解
本文演示了int、String、数组、list、set、map、Date等属性的注入。
其中Date类型的注入则是借助了Spring提供的属性编辑器来实现的,首先是用到的五个实体类
packagecom.jadyer.model;
importjava.util.Date;
importjava.util.List;
importjava.util.Map;
importjava.util.Set;
/**
*常见属性的注入
*@see包括int,String,Array,list,set,map,Date的注入
*/
publicclassBean11{
privateIntegerintValue;
privateStringstrValue;
privateString[]arrayValue;
privateListlistValue;
privateSetsetValue;
privateMapmapValue;
privateDatedateValue;
/*七个属性的setter和getter略*/
}
packagecom.jadyer.model;
publicclassBean22{
privateBean33bean33;
privateBean44bean4422;//注入:与属性名无关,与setBean44()有关
privateBean55bean55;
/*三个属性的setter和getter略*/
}
packagecom.jadyer.model;
publicclassBean33{
privateIntegerid;
privateStringname;
privateStringsex;
/*三个属性的setter和getter略*/
}
packagecom.jadyer.model;
publicclassBean44{
privateIntegerid;
privateStringname;
privateStringsex;
privateIntegerage;
/*四个属性的setter和getter略*/
}
packagecom.jadyer.model;
publicclassBean55{
privateStringpassword;
/*关于password的setter和getter略*/
}
然后是我们自定义的java.util.Date类型转换器
packagecom.jadyer.util;
importjava.beans.PropertyEditorSupport;
importjava.text.ParseException;
importjava.text.SimpleDateFormat;
importjava.util.Date;
/**
*java.util.Date属性编辑器。相当于类型转换器。这里是将String转为Date型
*@see----------------------------------------------------------------------------------------
*@see该示例主要让大家知道Spring也有这种机制,不是让大家以后写属性编辑器
*@see需要写属性编辑器的几率太少了,只要知道Spring也有类似的机制就可以了
*@see----------------------------------------------------------------------------------------
*@see所谓的属性编辑器,就是将Spring配置文件中的字符串转换成相应的Java对象
*@seeSpring内置了一些属性编辑器,也可以自定义属性编辑器
*@see自定义属性编辑器事,须继承PropertyEditorSupport类并覆写setAsText()方法
*@see最后再将自定义的属性编辑器注入到Spring中,即可
*@see----------------------------------------------------------------------------------------
*/
publicclassUtilDatePropertyEditorextendsPropertyEditorSupport{
privateStringpattern;//将转换的格式放到配置文件中,让Spring注入进来
publicvoidsetPattern(Stringpattern){
this.pattern=pattern;
}
@Override
publicvoidsetAsText(Stringtext)throwsIllegalArgumentException{
System.out.println("======UtilDatePropertyEditor.setAsText()======"+text);
try{
Datedate=newSimpleDateFormat(pattern).parse(text);
this.setValue(date);//注意:这里放进去的是一个java.util.Date对象,故输出的时间是默认的格式
}catch(ParseExceptione){
e.printStackTrace();
thrownewIllegalArgumentException(text);//继续向上抛参数非法的异常
}
}
}
用到的针对所有实体类的applicationContext-beans.xml文件
<?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd" default-lazy-init="true"> <!--default-lazy-init="true"属性的说明,详见InjectionTest.java类的第49行--> <!--default-autowire="byName或byType",这是Spri0ng提供的自动装配bean的两种方式byName和byType,详解略--> <!--***********************【LAZY====延迟初始化】***********************************************************************--> <!--执行testInjection22()时默认的会输出======UtilDatePropertyEditor.setAsText()======2010年06月04日--> <!--即此时并未设置default-lazy-init="true",这说明Bean11中的dateValue属性的值被注入了--> <!--事实上,默认的Spring在创建ApplicationContext时,会将配置文件中所有的对象实例化并进行注入--> <!--这样做的好处是如果Spring配置文件中的某些配置写错了,它立刻就能检测出来--> <!--而Struts1.X的配置文件,如果某个类写错了,是不会出问题的,只有在真正执行的时候,才会出问题--> <!--对于Spring而言,也可以采用相关的属性延迟配置文件的初始化,即default-lazy-init="true"--> <!--即只有真正使用的时候,再去New这个对象,再为属性注入。这时就涉及到LAZY,即延迟初始化--> <!--只需修改Spring配置文件即可,如<beansxsi:schemaLocation="http://www...."default-lazy-init="true">--> <!--这时的作用范围即整个配置文件,同理也可对各个<bean>标签的lazy-init属性进行单独配置--> <!--但一般都不会这么设置,而是在BeanFactory创建的时候,即完成注入,这样也便于检查出错误--> <!--*****************************************************************************************************************--> <beanid="bean11"class="com.jadyer.model.Bean11"> <propertyname="intValue"value="123"/><!--注入时,字符串123会自动转换为int型--> <propertyname="strValue"value="Hello_Spring"/> <propertyname="arrayValue"> <list> <value>array11</value> <value>array22</value> </list> </property> <propertyname="listValue"> <list> <value>list11</value> <value>list22</value> </list> </property> <propertyname="setValue"> <set> <value>set11</value> <value>set22</value> </set> </property> <propertyname="mapValue"> <map> <entrykey="key11"value="value11"/> <entrykey="key22"value="value22"/> </map> </property> <propertyname="dateValue"value="2010年06月04日"/><!--这里Date格式应与applicationContext-editor.xml配置的相同--> </bean> <beanid="bean22"class="com.jadyer.model.Bean22"> <propertyname="bean33"ref="bean33"/> <propertyname="bean44"ref="bean44"/> <propertyname="bean55"ref="bean55"/> </bean> <beanid="bean55"class="com.jadyer.model.Bean55"> <propertyname="password"value="123"/> </bean> </beans>
用到的针对公共实体类的applicationContext-common.xml文件
<?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!--利用抽象bean提取出公共配置--> <!--首先指定<bean>标签的abstract属性为true,然后在其它<bean>中指定其parent即可--> <beanid="AbstractBean"abstract="true"> <propertyname="id"value="2"/> <propertyname="name"value="张起灵"/> <propertyname="sex"value="男"/> </bean> <beanid="bean33"class="com.jadyer.model.Bean33"parent="AbstractBean"/> <beanid="bean44"class="com.jadyer.model.Bean44"parent="AbstractBean"> <propertyname="age"value="26"/> </bean> </beans> <!--使用AbstractBean之前的bean33和bean44的原形如下--> <!-- <beanid="bean33"class="com.jadyer.model.Bean33"> <propertyname="id"value="100"/> <propertyname="name"value="张三"/> <propertyname="sex"value="男"/> </bean> <beanid="bean44"class="com.jadyer.model.Bean44"> <propertyname="id"value="100"/> <propertyname="name"value="张三"/> <propertyname="sex"value="男"/> <propertyname="age"value="90"/> </bean> -->
用到的针对java.util.Date属性编辑器的applicationContext-editor.xml文件
<?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <beanid="utilDatePropertyEditor"class="com.jadyer.util.UtilDatePropertyEditor"> <propertyname="pattern"value="yyyy年MM月dd日"/> </bean> <!--查看源码得知,在CustomEditorConfigurer类的131行提供了一个setCustomEditors方法,所以就能够注入了--> <beanid="customEditors"class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <propertyname="customEditors"> <map> <entrykey="java.util.Date"value-ref="utilDatePropertyEditor"/> </map> </property> </bean> </beans> <!--也可以使用内部<bean>把utilDatePropertyEditor写在内部--> <!--这样就只有它自己有权使用了,外部就无法使用了--> <!--由于不提供外界访问,所以内部<bean>没有id属性--> <!--示例如下--> <!-- <beanid="customEditors"class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <propertyname="customEditors"> <map> <entrykey="java.util.Date"> <beanclass="com.jadyer.util.UtilDatePropertyEditor"> <propertyname="pattern"value="yyyy年MM月dd日"/> </bean> </entry> </map> </property> </bean> -->
最后是使用JUnit3.8写的单元测试类
packagecom.jadyer.junit;
importjunit.framework.TestCase;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
importcom.jadyer.model.Bean11;
importcom.jadyer.model.Bean22;
publicclassPropertyInjectionTestextendsTestCase{
privateApplicationContextfactory;
@Override
protectedvoidsetUp()throwsException{
/****====读取单一的配置文件====****/
//factory=newClassPathXmlApplicationContext("applicationContext.xml");
/****====利用数组读取多个配置文件====****/
//这样就会把两个配置文件作为一个来使用,表面上看是作为两个使用的
//其实内部是作为一个使用的,所以在多个配置文件中,里面的id不能重复
//但是name属性可以重复,就好像人的身份证编号和名字的区别是一样的
//String[]configLocations=newString[]{"applicationContext.xml","applicationContext-editor.xml"};
//factory=newClassPathXmlApplicationContext(configLocations);
/****=====利用*匹配模式读取多个配置文件====****/
//业界流行的一句话:约定优于配置
//所以说当有了一个统一的比较好的约定之后,就可以利用框架提供的功能,减少配置量
//另外:如果没有读取到applicationContext-*.xml,此时即便存在applicationContext.xml,它也不会读的
factory=newClassPathXmlApplicationContext("applicationContext-*.xml");
}
/**
*该方法演示的是常见属性的注入,包括int,String,Array,list,set,map,Date的注入
*@see其中Date类型的注入则是借助了Spring属性编辑器来实现的
*/
publicvoidtestInjection11(){
//Bean11bean11=newBean11();//若简单的new,那么它的属性是不会被注入的。注入的前提必须是从IoC容器中拿出来的,才会注入
Bean11bean11=(Bean11)factory.getBean("bean11");//此时bean11就是从IoC容器中获取到的,所以它的依赖就会被全部注入
System.out.println("bean11.intValue="+bean11.getIntValue());
System.out.println("bean11.strValue="+bean11.getStrValue());
System.out.println("bean11.arrayValue="+bean11.getArrayValue());
System.out.println("bean11.listValue="+bean11.getListValue());
System.out.println("bean11.setValue="+bean11.getSetValue());
System.out.println("bean11.mapValue="+bean11.getMapValue());
System.out.println("bean11.dateValue="+bean11.getDateValue());
}
/**
*该方法主要演示的是将公共的配置进行抽象,以减少配置量
*/
publicvoidtestInjection22(){
Bean22bean22=(Bean22)factory.getBean("bean22");
System.out.println("bean22.bean33.id="+bean22.getBean33().getId());
System.out.println("bean22.bean33.name="+bean22.getBean33().getName());
System.out.println("bean22.bean33.sex="+bean22.getBean33().getSex());
System.out.println("bean22.bean44.id="+bean22.getBean44().getId());
System.out.println("bean22.bean44.name="+bean22.getBean44().getName());
System.out.println("bean22.bean44.sex="+bean22.getBean44().getSex());
System.out.println("bean22.bean44.age="+bean22.getBean44().getAge());
System.out.println("bean22.bean55.password="+bean22.getBean55().getPassword());
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。