zoukankan      html  css  js  c++  java
  • Spring攻略学习笔记(4)解决构造程序歧义

             可以为<constructor-arg>元素指定type和index属性,帮助Spring查找预期的构造程序。最新版的Spring也可以使用name属性。

            (1)第一种情况

    /*
     * Copyright 2013-2015
     */
    package com.jackie.codeproject.springrecipesnote.springioc;
    
    /**
     * Title: SequenceGenerator.java 类的功能说明
     * 
     * @author jackie
     * @since Apr 13, 2013 12:56:57 PM
     * @version V1.0
     */
    public class SequenceGenerator {
    
        /**
         * @Fields prefix : 前缀
         */
        private String prefix;
    
        /**
         * @Fields suffix : 后缀
         */
        private String suffix;
    
        /**
         * @Fields initial : 初始值
         */
        private int initial;
    
        /**
          * @Fields counter : 计数器
          */
        private int counter;
    
        /**
          * 获取序列号,声明为同步,使其成为线程安全的方法
          * @author jackie  
          * @date Apr 13, 2013
          * @return    
          * @return String   
          */
        public synchronized String getSquence() {
            StringBuffer buffer = new StringBuffer();
            buffer.append(prefix);
            buffer.append(initial + counter++);
            buffer.append(suffix);
            return buffer.toString();
        }
    
        /**
          * <p>Title: </p>
          * <p>Description:构造函数1 </p>
          * @param prefix
          * @param suffix
          * @param initial
          */  
        public SequenceGenerator(String prefix, String suffix, int initial) {
            this.prefix = prefix;
            this.suffix = suffix;
            this.initial = initial;
        }
    
        /**
          * <p>Title: </p>
          * <p>Description:构造函数2 </p>
          * @param prefix
          * @param suffix
          */
        public SequenceGenerator(String prefix, String suffix) {
            this.prefix = prefix;
            this.suffix = suffix;
        }
        
        /**
         * <p>Title: </p>
         * <p>Description:构造函数3 </p>
         * @param prefix
         * @param initial
         */
       public SequenceGenerator(String prefix, int initial) {
           this.prefix = prefix;
           this.initial = initial;
       }
    
        /**
         * @param prefix
         *            the prefix to set
         */
        public void setPrefix(String prefix) {
            this.prefix = prefix;
        }
    
        /**
         * @param suffix
         *            the suffix to set
         */
        public void setSuffix(String suffix) {
            this.suffix = suffix;
        }
    
        /**
         * @param initial
         *            the initial to set
         */
        public void setInitial(int initial) {
            this.initial = initial;
        }
    }
    

    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"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
        <bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
    	<constructor-arg value="30" />
    	<constructor-arg value="100000" />
    	<property name="suffix" value="A" />
        </bean>
    </beans>

      测试程序:

     // 使用ClassPathXmlApplicationContext是ApplicationContext接口的一个实现,它可以从classpath中装入一个XML配置文件
     ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
     // 使用getBean方法并为其传递配置的唯一的Bean名称,其返回类型为Object,须强制转型。
     SequenceGenerator sequenceGenerator = (SequenceGenerator) applicationContext.getBean("sequenceGenerator");
     System.out.println(sequenceGenerator.getSquence());
     System.out.println(sequenceGenerator.getSquence());

    输出结果:300A

                        301A

    分析:出现这结果的原因是调用了带有prefix和suffix参数的构造程序,而不是带有prefix和initial参数的。因为Spring默认将两个参数都解析为String类型,第一个构造程序不需要类型转换,所以被认定最合适。为了指定参数的预期类型,你必须设置<constructor-arg>中的type属性。

    <bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
       <constructor-arg type="java.lang.String" value="30" />
       <constructor-arg type="int" value="100000" />
       <property name="suffix" value="A" />
    </bean>

    (2)第二种情况

      在SequenceGenerator中再添加以下构造函数:

      /**
        * <p>Title: </p>
        * <p>Description: </p>
        * @param suffix
        * @param initial
        */
      public SequenceGenerator(int initial, String suffix) {
          this.suffix = suffix;
          this.initial = initial;
      }

    修改Bean配置文件:

    <bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
       <constructor-arg type="int" value="100000" />
       <constructor-arg type="java.lang.String" value="A" />
       <property name="prefix" value="30" />
    </bean>

    书上说再次运行测试程序可能得到正确结果,或者得到以下意外结果:

        30100000null

        30100000null

    原因是Spring认为SequenceGenerator(String prefix, int initial) 和SequenceGenerator(int initial, String suffix)这两个构造函数是一样的,不会考虑参数出现在XML中的顺序,所以会造成歧义。但是我本人的程序跑起来都是使用的SequenceGenerator(int initial, String suffix),不知是不是最新版的Spring考虑了参数在XML文件中的位置,如有知道的牛人麻烦告知一声。

         可以使用<constructor-arg>的index属性明确指出参数索引值。设置了type和Index属性,Spring就能够准确的为Bean找到预期的构造函数。

    <bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
       <constructor-arg type="int" index="0" value="100000" />
       <constructor-arg type="java.lang.String" index="1" value="A" />
       <property name="prefix" value="30" />
    </bean>
    

           最简单的还是使用<constructor-arg>的name属性:

    <bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
       <constructor-arg name="initial" value="100000" />
       <constructor-arg name="suffix" value="A" />
       <property name="prefix" value="30" />
    </bean>


  • 相关阅读:
    总结6.6 PHP后台登录和文件上传
    【017期】JavaSE面试题(十七):JVM之内存模型
    【016期】JavaSE面试题(十六):反射
    【015期】JavaSE面试题(十五):网络IO流
    【014期】JavaSE面试题(十四):基本IO流
    【013期】JavaSE面试题(十三):多线程(3)
    【012期】JavaSE面试题(十二):多线程(2)
    【011期】JavaSE面试题(十一):多线程(1)
    【010期】JavaSE面试题(十):集合之Map
    【009期】JavaSE面试题(九):集合之Set
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3030808.html
Copyright © 2011-2022 走看看