Spring中属性注入详解_java

本文演示了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());
  }
} 

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索spring
, 属性
注入
spring 注入详解、spring 依赖注入详解、spring 属性注入、spring注入静态属性、spring 属性注入 注解,以便于您获取更多的相关知识。

时间: 2024-10-03 10:04:44

Spring中属性注入详解_java的相关文章

面向对象编程依赖注入详解_java

说说依赖注入 在面向对象编程中,我们经常处理处理的问题就是解耦,程序的耦合性越低表明这个程序的可读性以及可维护性越高.控制反转(Inversion of Control或IoC)就是常用的面向对象编程的设计原则,使用这个原则我们可以降低耦合性.其中依赖注入是控制反转最常用的实现. 什么是依赖 依赖是程序中常见的现象,比如类Car中用到了GasEnergy类的实例energy,通常的做法就是在Car类中显式地创建GasEnergy类的实例,并赋值给energy.如下面的代码 interface E

HttpClient 在Java项目中的使用详解_java

Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性.因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入. 一.简介 HttpClient是Apache Jakarta Common下的子项目,用

Java 中ThreadLocal类详解_java

ThreadLocal类,代表一个线程局部变量,通过把数据放在ThreadLocal中,可以让每个线程创建一个该变量的副本.也可以看成是线程同步的另一种方式吧,通过为每个线程创建一个变量的线程本地副本,从而避免并发线程同时读写同一个变量资源时的冲突. 示例如下: import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import ja

Java中static作用详解_java

static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static修饰的成员变量和成员方法独立于该类的任何对象.也就是说,它不依赖类特定的实例,被类的所有实例共享. 只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们.因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象. 用public修饰的static成员变量和成员方法本质是

Spring中的AOP详解

本文摘自pandonix的博客.   此前对于AOP的使用仅限于声明式事务,除此之外在实际开发中也没有遇到过与之相关的问题.最近项目中遇到了以下几点需求,采用AOP来解决.一方面是为了以更加灵活的方式来解决问题,另一方面是借此机会深入学习Spring AOP相关的内容.本文是权当本人的自己AOP学习笔记,以下需求不用AOP肯定也能解决,至于是否牵强附会,仁者见仁智者见智. 面对需求: ①对部分函数的调用进行日志记录,用于观察特定问题在运行过程中的函数调用情况. ②监控部分重要函数,若抛出指定的异

Spring中的Scope详解

spring 默认scope 是单例模式 这样只会创建一个Action对象 每次访问都是同一个Action对象,数据不安全 struts2 是要求 每次次访问 都对应不同的Action scope="prototype" 可以保证 当有请求的时候 都创建一个Action对象   <bean id="meetAction" class="com.web.actions.MeetsAction"   scope="prototype&

在Spring中进行集成测试详解

在单元测试时,我们尽量在屏蔽模块间相互干扰的情况下,重点关注模块内部逻辑的 正确性.而集成测试则是在将模块整合在一起后进行的测试,它的目的在于发现一些模块 间整合的问题.有些功能很难通过模拟对象进行模拟,相反它们往往只能在真实模块整合 后,才能真正运行起来,如事务管理就是其中比较典型的例子. 按照Spring的推荐(原话:You should not normally use the Spring container for unit tests: simply populate your PO

Java中的泛型详解_java

所谓泛型:就是允许在定义类.接口指定类型形参,这个类型形参在将在声明变量.创建对象时确定(即传入实际的类型参数,也可称为类型实参) 泛型类或接口 "菱形"语法 复制代码 代码如下: //定义   public interface List<E> extends Collection<E>    public class HashMap<K,V> extends AbstractMap<K,V>  implements Map<K,V

Java中字符编码格式详解_java

一.前言 在分析Comparable和Comparator的时候,分析到了String类的compareTo方法,String底层是用char[]数组来存放元素,在比较的时候是比较的两个字符串的字符,字符用char来存储,此时,突然想到,Java里面的char可以存放中文吗?后来发现是可以的,并且由此也引出了Java中字符的编码格式问题. 二.Java存储格式 在Java中,如下代码获取了字符'张'的各种编码格式. import java.io.UnsupportedEncodingExcept