zoukankan      html  css  js  c++  java
  • Spring构造方法注入类型歧义

    在Spring框架中,当一个类包含多个构造函数带的参数相同,它总是会造成构造函数注入参数类型歧义的问题。

    问题

    让我们来看看这个客户 bean 实例。它包含两个构造方法,均接受3个不同的数据类型参数。
    package com.yiibai.common;
    
    public class Customer 
    {
    	private String name;
    	private String address;
    	private int age;
    	
    	public Customer(String name, String address, int age) {
    		this.name = name;
    		this.address = address;
    		this.age = age;
    	}
    	
    	public Customer(String name, int age, String address) {
    		this.name = name;
    		this.age = age;
    		this.address = address;
    	}
    	//getter and setter methods
    	public String toString(){
    		return " name : " +name + "
     address : "
                   + address + "
     age : " + age;
    	}
    
    }
    在Spring bean 的配置文件中,通过传递一个“yiibai' 的名字,地址为'188',以及年龄为'28'。
    <!--Spring-Customer.xml-->
    <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-2.5.xsd">
    
    	<bean id="CustomerBean" class="com.yiibai.common.Customer">
    
    		<constructor-arg>
    			<value>yiibai</value>
    		</constructor-arg>
    		
    		<constructor-arg>
    			<value>188</value>
    		</constructor-arg>
    		
    		<constructor-arg>
    			<value>28</value>
    		</constructor-arg>
            </bean>
    
    </beans>
    运行它,你期望的结果是什么?
    package com.yiibai.common;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class App 
    {
        public static void main( String[] args )
        {
        	ApplicationContext context = 
        	  new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"});
    
        	Customer cust = (Customer)context.getBean("CustomerBean");
        	System.out.println(cust);
        }
    }

    输出结果

    name : yiibai
     address : 28
     age : 188
    其结果不是我们所期望的,第一个构造器不执行,而是第二构造函数运行。在Spring参数类型'188' 能够转换成int,所以Spring只是转换它,并采用第二个构造来执行,即使你认为它应该是一个字符串。
    另外,如果Spring不能解决使用哪个构造函数,它会提示以下错误信息
    constructor arguments specified but no matching constructor 
    found in bean 'CustomerBean' (hint: specify index and/or 
    type arguments for simple parameters to avoid type ambiguities)

    解决

    为了解决这个问题,应该为构造函数指定的确切数据类型,通过像这样类型的属性:
    <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-2.5.xsd">
    
    	<bean id="CustomerBean" class="com.yiibai.common.Customer">
    	
    		<constructor-arg type="java.lang.String">
    			<value>yiibai</value>
    		</constructor-arg>
    		
    		<constructor-arg type="java.lang.String">
    			<value>188</value>
    		</constructor-arg>
    		
    		<constructor-arg type="int">
    			<value>28</value>
    		</constructor-arg>
    		
    	</bean>
    
    </beans>
    再次运行它,现在得到你所期望的。
    输出结果
    name : yiibai
     address : 188
     age : 28

    这是一个很好的做法,显式声明每个构造函数参数的数据类型,以避免上述构造注入型歧义的问题。
     
    http://www.yiibai.com/spring/constructor-injection-type-ambiguities-in-spring.html
  • 相关阅读:
    《Metasploit 渗透测试魔鬼训练营》 攻击机无法攻击靶机
    Ubuntu 解压 RAR
    verilog实验2:基于FPGA的59秒计时器设计
    verilog实验1:基于FPGA蜂鸣器演奏乐曲并数码管显示
    Java基础之反射和动态代理
    Redis初探
    Rest(表述性状态转移)
    深入理解MVC模式
    @Controller和@RestController的区别
    solrconfig.xml和schema.xml说明
  • 原文地址:https://www.cnblogs.com/soundcode/p/6367211.html
Copyright © 2011-2022 走看看