首页 > 编程 > Java > 正文

Spring中属性注入详解

2019-11-26 13:41:24
字体:
来源:转载
供稿:网友

本文演示了int、String、数组、list、set、map、Date等属性的注入。
其中Date类型的注入则是借助了Spring提供的属性编辑器来实现的,首先是用到的五个实体类

package com.jadyer.model; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; /**  * 常见属性的注入  * @see 包括int,String,Array,list,set,map,Date的注入  */ public class Bean11 {   private Integer intValue;   private String strValue;   private String[] arrayValue;   private List listValue;   private Set setValue;   private Map mapValue;   private Date dateValue;   /* 七个属性的setter和getter略 */ }   package com.jadyer.model; public class Bean22 {   private Bean33 bean33;   private Bean44 bean4422; //注入:与属性名无关,与setBean44()有关   private Bean55 bean55;   /* 三个属性的setter和getter略 */ }   package com.jadyer.model; public class Bean33 {   private Integer id;   private String name;   private String sex;   /* 三个属性的setter和getter略 */ }   package com.jadyer.model; public class Bean44 {   private Integer id;   private String name;   private String sex;   private Integer age;   /* 四个属性的setter和getter略 */ }   package com.jadyer.model; public class Bean55 {   private String password;   /* 关于password的setter和getter略 */ } 

然后是我们自定义的java.util.Date类型转换器

package com.jadyer.util;  import java.beans.PropertyEditorSupport; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;  /**  * java.util.Date属性编辑器。相当于类型转换器。这里是将String转为Date型  * @see ----------------------------------------------------------------------------------------  * @see 该示例主要让大家知道Spring也有这种机制,不是让大家以后写属性编辑器  * @see 需要写属性编辑器的几率太少了,只要知道Spring也有类似的机制就可以了  * @see ----------------------------------------------------------------------------------------  * @see 所谓的属性编辑器,就是将Spring配置文件中的字符串转换成相应的Java对象  * @see Spring内置了一些属性编辑器,也可以自定义属性编辑器  * @see 自定义属性编辑器事,须继承PropertyEditorSupport类并覆写setAsText()方法  * @see 最后再将自定义的属性编辑器注入到Spring中,即可  * @see ----------------------------------------------------------------------------------------  */ public class UtilDatePropertyEditor extends PropertyEditorSupport {   private String pattern; //将转换的格式放到配置文件中,让Spring注入进来   public void setPattern(String pattern) {     this.pattern = pattern;   }      @Override   public void setAsText(String text) throws IllegalArgumentException {     System.out.println("======UtilDatePropertyEditor.setAsText()======" + text);     try {       Date date = new SimpleDateFormat(pattern).parse(text);       this.setValue(date); //注意:这里放进去的是一个java.util.Date对象,故输出的时间是默认的格式     } catch (ParseException e) {       e.printStackTrace();       throw new IllegalArgumentException(text); //继续向上抛参数非法的异常     }   } } 

用到的针对所有实体类的applicationContext-beans.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:aop="http://www.springframework.org/schema/aop"     xmlns:tx="http://www.springframework.org/schema/tx"     xsi:schemaLocation="       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd       http://www.springframework.org/schema/tx http://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配置文件即可,如<beans xsi:schemaLocation="http://www...." default-lazy-init="true"> -->   <!-- 这时的作用范围即整个配置文件,同理也可对各个<bean>标签的lazy-init属性进行单独配置 -->   <!-- 但一般都不会这么设置,而是在BeanFactory创建的时候,即完成注入,这样也便于检查出错误 -->   <!-- ***************************************************************************************************************** -->      <bean id="bean11" class="com.jadyer.model.Bean11">     <property name="intValue" value="123"/><!-- 注入时,字符串123会自动转换为int型 -->     <property name="strValue" value="Hello_Spring"/>     <property name="arrayValue">       <list>         <value>array11</value>         <value>array22</value>       </list>     </property>     <property name="listValue">       <list>         <value>list11</value>         <value>list22</value>       </list>     </property>     <property name="setValue">       <set>         <value>set11</value>         <value>set22</value>       </set>     </property>     <property name="mapValue">       <map>         <entry key="key11" value="value11"/>         <entry key="key22" value="value22"/>       </map>     </property>     <property name="dateValue" value="2010年06月04日"/><!-- 这里Date格式应与applicationContext-editor.xml配置的相同 -->   </bean>      <bean id="bean22" class="com.jadyer.model.Bean22">     <property name="bean33" ref="bean33"/>     <property name="bean44" ref="bean44"/>     <property name="bean55" ref="bean55"/>   </bean>      <bean id="bean55" class="com.jadyer.model.Bean55">     <property name="password" value="123"/>   </bean> </beans> 

用到的针对公共实体类的applicationContext-common.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:aop="http://www.springframework.org/schema/aop"     xmlns:tx="http://www.springframework.org/schema/tx"     xsi:schemaLocation="       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">          <!-- 利用抽象bean提取出公共配置 -->   <!-- 首先指定<bean>标签的abstract属性为true,然后在其它<bean>中指定其parent即可 -->   <bean id="AbstractBean" abstract="true">     <property name="id" value="2"/>     <property name="name" value="张起灵"/>     <property name="sex" value="男"/>   </bean>   <bean id="bean33" class="com.jadyer.model.Bean33" parent="AbstractBean"/>   <bean id="bean44" class="com.jadyer.model.Bean44" parent="AbstractBean">     <property name="age" value="26"/>   </bean> </beans>  <!-- 使用AbstractBean之前的bean33和bean44的原形如下 --> <!--  <bean id="bean33" class="com.jadyer.model.Bean33">   <property name="id" value="100"/>   <property name="name" value="张三"/>   <property name="sex" value="男"/> </bean> <bean id="bean44" class="com.jadyer.model.Bean44">   <property name="id" value="100"/>   <property name="name" value="张三"/>   <property name="sex" value="男"/>   <property name="age" value="90"/> </bean>  --> 

用到的针对java.util.Date属性编辑器的applicationContext-editor.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:aop="http://www.springframework.org/schema/aop"     xmlns:tx="http://www.springframework.org/schema/tx"     xsi:schemaLocation="       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">          <bean id="utilDatePropertyEditor" class="com.jadyer.util.UtilDatePropertyEditor">     <property name="pattern" value="yyyy年MM月dd日"/>   </bean>      <!-- 查看源码得知,在CustomEditorConfigurer类的131行提供了一个setCustomEditors方法,所以就能够注入了 -->   <bean id="customEditors" class="org.springframework.beans.factory.config.CustomEditorConfigurer">     <property name="customEditors">       <map>         <entry key="java.util.Date" value-ref="utilDatePropertyEditor"/>       </map>     </property>   </bean> </beans>  <!-- 也可以使用内部<bean>把utilDatePropertyEditor写在内部 --> <!-- 这样就只有它自己有权使用了,外部就无法使用了 --> <!-- 由于不提供外界访问,所以内部<bean>没有id属性 --> <!-- 示例如下 --> <!--  <bean id="customEditors" class="org.springframework.beans.factory.config.CustomEditorConfigurer">   <property name="customEditors">     <map>       <entry key="java.util.Date">         <bean class="com.jadyer.util.UtilDatePropertyEditor">           <property name="pattern" value="yyyy年MM月dd日"/>         </bean>       </entry>     </map>   </property> </bean>  -->

 

最后是使用JUnit3.8写的单元测试类

package com.jadyer.junit;  import junit.framework.TestCase;  import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  import com.jadyer.model.Bean11; import com.jadyer.model.Bean22;  public class PropertyInjectionTest extends TestCase {   private ApplicationContext factory;    @Override   protected void setUp() throws Exception {     /****====读取单一的配置文件====****/     //factory = new ClassPathXmlApplicationContext("applicationContext.xml");          /****====利用数组读取多个配置文件====****/     //这样就会把两个配置文件作为一个来使用,表面上看是作为两个使用的     //其实内部是作为一个使用的,所以在多个配置文件中,里面的id不能重复     //但是name属性可以重复,就好像人的身份证编号和名字的区别是一样的     //String[] configLocations = new String[]{"applicationContext.xml", "applicationContext-editor.xml"};     //factory = new ClassPathXmlApplicationContext(configLocations);          /****=====利用 * 匹配模式读取多个配置文件====****/     //业界流行的一句话:约定优于配置     //所以说当有了一个统一的比较好的约定之后,就可以利用框架提供的功能,减少配置量     //另外:如果没有读取到applicationContext-*.xml,此时即便存在applicationContext.xml,它也不会读的     factory = new ClassPathXmlApplicationContext("applicationContext-*.xml");   }    /**    * 该方法演示的是常见属性的注入,包括int,String,Array,list,set,map,Date的注入    * @see 其中Date类型的注入则是借助了Spring属性编辑器来实现的    */   public void testInjection11() {     //Bean11 bean11 = new Bean11(); //若简单的new,那么它的属性是不会被注入的。注入的前提必须是从IoC容器中拿出来的,才会注入     Bean11 bean11 = (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());   }      /**    * 该方法主要演示的是将公共的配置进行抽象,以减少配置量    */   public void testInjection22() {     Bean22 bean22 = (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());   } } 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表