系统化的学习技术、研究技术而不是使用技术

Spring Framework 3.2.5 初始化 bean 属性时踩坑

2019/05/22 15:10:47 | 浏览(107) | Spring

项目使用了 Spring Framework 3.2.5 的版本,这个问题是在使用 Mybatis-Plus 2.3.3 配置属性时遇到的。

本文适用对象:使用 Spring Framework 3.2.7 以下版本者

代码:

public enum WeekDay {
    MONDAY(1, "星期一"),TUESDAY(2, "星期二"),WEDNESDAY(3, "星期三"),THURSDAY(4, "星期四"),
    FRIDAY(5, "星期五"),SATURDAY(6, "星期六"),SUNDAY(7, "星期日");

    private int key;
    private String desc;
    /* 省略构造方法 */

    public static WeekDay fromKey(int weekDayKey) {
        for (WeekDay weekDay : WeekDay.values()) {
            if (weekDay.key == weekDayKey) {
                return weekDay;
            }
        }
        return null;
    }
}
public class WeekConfig {
    private WeekDay luckyDay;
    // 此处做类型转换,将 int 转为 enum ,这里就是出现坑的地方
    public void setLuckyDay(int luckyDay) {
        this.luckyDay = WeekDay.fromKey(luckyDay);
    }
}

配置文件:

<bean id="weekConfig" class="tk.winshu.config.WeekConfig">
    <property name="luckyDay" value="2"/>
</bean>

启动时出现异常:

Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'tk.winshu.config.WeekDay' for property 'luckyDay'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [tk.winshu.config.WeekDay] for property 'luckyDay': no matching editors or conversion strategy found
    at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:463)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:494)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:488)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1463)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1422)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1158)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    ... 11 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [tk.winshu.config.WeekDay] for property 'luckyDay': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:267)
    at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:448)
    ... 17 more

解决办法(三选一即可):

  1. 升级到高版本的 Spring Framework (至少升级到 Spring 3.2.7
  2. 使用 JavaConfig 进行配置(Spring 3.x引入了注解@Bean)
  3. 避免使用类型转换(比如简单类型->枚举)

BUG 出现版本和修复版本

修复版本:Spring Framework 3.2.7
目前版本:Spring Framework 3.2.5

BUG 修复

// BeanWrapperImpl
// 3.2.5 pd.getPropertyType() 返回的是属性类型,而 td.getType() 返回的是 setter 入参类型
private Object convertForProperty(String propertyName, Object oldValue, Object newValue, PropertyDescriptor pd) throws TypeMismatchException {
    return this.convertIfNecessary(propertyName, oldValue, newValue, pd.getPropertyType(), new TypeDescriptor(property(pd)));
}
// 3.2.7
private Object convertForProperty(String propertyName, Object oldValue, Object newValue, TypeDescriptor td) throws TypeMismatchException {
    return this.convertIfNecessary(propertyName, oldValue, newValue, td.getType(), td);
}

总结

一代版本一代坑,代代版本有 BUG 。

适当的升级版本有助于解决 BUG ,但也有可能引入新的 BUG 。

最后更新于 2019/05/22 15:13:29

留言(0)

给我留言