在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 + "\n address : "
+ address + "\n 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

Spring构造方法注入类型歧义的更多相关文章

  1. spring之注入类型

    spring有三种注入类型: set注入: 构造注入: 接口注入: 一.set注入(引用spring官方文档中的例子)(用的最多) 1.首先在代码中我们需要编写成员变量的set方法,如下所示,一般情况 ...

  2. spring 构造方法注入和setter方法注入的XML表达

    1.构造方法注入 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC ...

  3. Spring自动注入,类型注入、名称注入(两种方式)

    参考: https://blog.csdn.net/qq_41767337/article/details/89002422 https://www.iteye.com/blog/breezylee- ...

  4. Spring Bean 注入 1 - 构造方法注入,属性注入,自动装配

    1.代码结构图 xxx 2.bean代码 package com.xxx.bean; /** * Created with IntelliJ IDEA. * User: zhenwei.liu * D ...

  5. Spring容器三种注入类型

    Spring注入有三种方式: 1.Set注入(使用最多) 2.构造器注入(使用不多) 3.接口注入(几乎不用)不做测试了 1.Set注入:所谓Set注入就是容器内部调用了bean的Set***方法,注 ...

  6. Spring属性注入、构造方法注入、工厂注入以及注入参数(转)

    Spring 是一个开源框架. Spring 为简化企业级应用开发而生(对比EJB2.0来说). 使用 Spring 可以使简单的 JavaBean 实现以前只有 EJB 才能实现的功能.Spring ...

  7. Spring依赖注入的方式、类型、Bean的作用域、自动注入、在Spring配置文件中引入属性文件

    1.Spring依赖注入的方式 通过set方法完成依赖注入 通过构造方法完成依赖注入 2.依赖注入的类型 基本数据类型和字符串 使用value属性 如果是指向另一个对象的引入 使用ref属性 User ...

  8. Spring 03: 基于xml的构造方法注入

    构造方法注入 具体有3种注入方式:通过构造方法的 a.参数名称注入 b.参数下标注入 c.默认参数顺序注入 参数名称注入 School实体类 package com.example.pojo03; p ...

  9. Spring通过构造方法注入的四种方式

    通过构造方法注入,就相当于给构造方法的参数传值 set注入的缺点是无法清晰表达哪些属性是必须的,哪些是可选 的,构造注入的优势是通过构造强制依赖关系,不可能实例化不 完全的或无法使用的bean. Me ...

随机推荐

  1. 对 makefile 中 .DEFAULT 的理解

    上例子: all:gao @echo "final".DEFAULT: @echo "In default" 由于 gao 是一个前提条件,但是 makefil ...

  2. 在ubuntu 上安装pycharm

    1.首先在官网下载pycharm并进行提取,将提取的文件夹放在/usr下面(或者任意位置) 2.然后vi /etc/hosts 编辑 将0.0.0.0 account.jetbrains.com添加到 ...

  3. go语言入门(二)

    Go 语言变量 Go 语言变量名由字母.数字.下划线组成,其中首个字母不能为数字. 声明变量的一般形式是使用 var 关键字: var identifier type 变量声明 第一种,指定变量类型, ...

  4. Android: 在onCreate()中获得对象尺寸

    onCreate() 中 View 尚未绘制完成 很多时候,我们需要在某个界面刚刚加载的时候,执行一些对 View 进行操作的代码,通常我们把这些代码放在 Activity 的 onCreate() ...

  5. fedroa20 没法开启ntpd服务器

    1现象:ntpd老是没法开启,ntpd -d显示有个进程占用123端口. [root@vd13crmtb01 ~]# systemctl enable ntpd.service         //开 ...

  6. TCP三次链接和四次断开

    经典的三次握手示意图:(#add,“握手”即图中左边到右边的连线)    经典的四次握手关闭图:    TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即t ...

  7. Effective C++笔记(六):继承与面向对象设计

    参考:http://www.cnblogs.com/ronny/p/3756494.html 条款32:确定你的public继承塑模出is-a关系 “public继承”意味着is-a.适用于base ...

  8. HDU 2859 Phalanx(二维DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2859 题目大意:对称矩阵是这样的矩阵,它由“左下到右”线对称. 相应位置的元素应该相同. 例如,这里是 ...

  9. 实习day2:@2X图片,git,coding.net,

    @2X是5和6系列的图片,@3X是6P等大屏的图片 本公司目前只用@2X的图片适配. 比如20X27的图片 1x, 就是原始大小: 用2X, 就除以2,变成10X13.5: 如果用3X的, 就除以3, ...

  10. mysql 导入数据到postgresql

    创建PG的表脚本 DROP TABLE IF EXISTS "public"."t_resource_info"; CREATE TABLE "pub ...