各位专家,您好,我想弄清楚为什么我的案例无法正常工作。
情况:
有一个名为AbstractCheckoutStepValidator的类,这是它的 xml 配置:
<bean id="abstractCheckoutStepValidator" class="...checkout.steps.validation.AbstractCheckoutStepValidator" abstract="true">
<property name="checkoutFlowFacade" ref="checkoutFlowFacade"/>
<property name="checkoutFacade" ref="checkoutFacade"/>
</bean>
和代码:
public abstract class AbstractCheckoutStepValidator implements CheckoutStepValidator
{
private CheckoutFacade checkoutFacade;
private CheckoutFlowFacade checkoutFlowFacade;
@Override
public abstract ValidationResults validateOnEnter(final RedirectAttributes redirectAttributes);
@Override
public ValidationResults validateOnExit()
{
return ValidationResults.SUCCESS;
}
public CheckoutFacade getCheckoutFacade()
{
return checkoutFacade;
}
@Required
public void setCheckoutFacade(final CheckoutFacade checkoutFacade)
{
this.checkoutFacade = checkoutFacade;
}
public CheckoutFlowFacade getCheckoutFlowFacade()
{
return checkoutFlowFacade;
}
@Required
public void setCheckoutFlowFacade(final CheckoutFlowFacade checkoutFlowFacade)
{
this.checkoutFlowFacade = checkoutFlowFacade;
}
}
这是DefaultMultiStepCheckoutStepValidator类,它扩展AbstractCheckoutStepValidator并覆盖它的 getter
public class DefaultMultiStepCheckoutStepValidator extends AbstractCheckoutStepValidator {
private static final Logger LOGGER = Logger.getLogger(DefaultMultiStepCheckoutStepValidator.class);
@Resource(name = "companyCheckoutFacade")
private CompanyCheckoutFacade companyCheckoutFacade;
// omitted code
@Override
public CompanyCheckoutFacade getCheckoutFacade() {
return companyCheckoutFacade;
}
}
这个类的xml配置:
<bean id="defaultMultiStepCheckoutValidator" class="...checkout.steps.validation.impl.DefaultMultiStepCheckoutStepValidator" parent="abstractCheckoutStepValidator" />
从技术角度来看应该没问题,如果 getter 返回父类,那么我可以使用它的子类之一,在我的情况下它是CompanyCheckoutFacade extends CheckoutFacade。(我有一个类似的例子,比如这里:
@Override
protected CompanyCartFacade getCartFacade() {
return (CompanyCartFacade) super.getCartFacade();
}
但在这里我确定返回的 bean 可以转换为这个子类,这就是为什么我从父类调用 getter 并且这个 getter 在父类或子类中工作正常)
同样在代码中,我通过注入依赖注释并且此字段与父类中的 checkoutFacade 字段无关...如果我使用上面的代码启动服务器,那么我收到以下错误:
Error creating bean with name 'defaultMultiStepCheckoutValidator' defined in ServletContext resource [/WEB-INF/config/multi-step-checkout-config.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type '...order.impl.DefaultCheckoutFacade' to required type '...facades.order.CompanyCheckoutFacade' for property 'checkoutFacade'; nested exception is java.lang.IllegalStateException: Cannot convert value of type '...order.impl.DefaultCheckoutFacade' to required type '...facades.order.CompanyCheckoutFacade' for property 'checkoutFacade': no matching editors or conversion strategy found
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.lambda$resolveManagedMap$1(BeanDefinitionValueResolver.java:453) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[?:?]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedMap(BeanDefinitionValueResolver.java:451) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:181) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1697) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1442) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.lambda$resolveManagedMap$1(BeanDefinitionValueResolver.java:453) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[?:?]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedMap(BeanDefinitionValueResolver.java:451) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:181) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1697) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1442) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeanByName(AbstractAutowireCapableBeanFactory.java:453) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:527) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:497) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:650) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:239) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:318) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
... 27 more
问题是:
从上面的错误我真的不明白为什么spring会尝试将类型'...order.impl.DefaultCheckoutFacade'的属性值转换为属性'checkoutFacade'所需的类型'...facades.order.CompanyCheckoutFacade' . 我没有在我的 getter 中的任何地方使用 checkoutFacade 属性。
DefaultCheckoutFacade是CheckoutFacade接口的默认实现,我确信 xml 配置中的 checkoutFacade ref 指的是正确的实现,这里:
<alias name="defaultCheckoutFacade" alias="checkoutFacade"/>
<bean id="defaultCheckoutFacade" class="...order.impl.DefaultCheckoutFacade">
// properties are omitted
</bean>
我的班级我说getter应该返回不同的实现,就是这样。为了摆脱这个错误,我只需要重命名 getter 并且不要覆盖父类中的那个,但我不明白为什么覆盖 getter 的方法不起作用?
感谢您花时间/回答问题。