【问题标题】:Error creating bean创建 bean 时出错
【发布时间】:2012-12-16 13:11:50
【问题描述】:

这是我得到的错误跟踪:

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DefaultPG' defined in file [C:\Users\ali\workspace\tms-payment\PaymentGatewayConfigurations.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'paymentGatewayName' of bean class [me.tms.payment.common.DefaultPaymentGateway]: Bean property 'paymentGatewayName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1361)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1075)
at me.tms.payment.common.DefaultPaymentGateway.getPaymentGatewayName(DefaultPaymentGateway.java:12)
at me.tms.payment.test.DefaultPaymentGatewayTest.test(DefaultPaymentGatewayTest.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'paymentGatewayName' of bean class [me.tms.payment.common.DefaultPaymentGateway]: Bean property 'paymentGatewayName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1024)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:900)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:58)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1358)
... 30 more

这是报告的课程:

package me.tms.payment.common;

import me.tms.payment.configurations.ConfigurationsUtility;
import me.tms.payment.configurations.PaymentGatewayConfigurations;

 public class DefaultPaymentGateway {

private static String paymentGatewayName;

@SuppressWarnings("static-access")
public static String getPaymentGatewayName() {
    DefaultPaymentGateway defaultPaymentGateway = (DefaultPaymentGateway)ConfigurationsUtility.getBeanConfigurationContext(PaymentGatewayConfigurations.configurationsFile).getBean("DefaultPG");
     setPaymentGatewayName(defaultPaymentGateway.paymentGatewayName);
    return paymentGatewayName;
}

public static void setPaymentGatewayName(String paymentGatewayName) {
    DefaultPaymentGateway.paymentGatewayName = paymentGatewayName;
}

}

这是豆子:

<!-- Default payment gateway properties -->
<bean id="DefaultPG" class="me.tms.payment.common.DefaultPaymentGateway" scope="prototype">
    <property name="paymentGatewayName" value="VPC"></property>
</bean> 

有什么问题?

【问题讨论】:

标签: java spring junit javabeans


【解决方案1】:

Bean property 'paymentGatewayName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

原因是 paymentGatewayName 是静态的。它不是对象的属性,而是在您的 jvm 中只有一个 BeanName.paymentGatewayName。您不能自动装配静态 bean 属性。

删除

&lt;property name="paymentGatewayName" value="VPC"&gt;&lt;/property&gt; 并将其设置在您的类中。

private static String paymentGatewayName="VPC";

或使其成为非静态的。

【讨论】:

    【解决方案2】:

    不要使用静态设置器,删除设置器中的静态关键字

    【讨论】:

      【解决方案3】:

      你不能在 bean 中注入静态属性,这是 Spring 的缺点。
      相同的 Jira https://jira.springsource.org/browse/SPR-3845

      解决方法

      1. 创建不带任何注释的类的静态属性
      2. 标记类以使用@Component 注入静态属性,以便在 Spring 启动时注入这些属性
      3. 创建一个设置静态属性的非静态 setter 方法
      4. 用@Autowired(required = true)标记setter方法

      来源:http://www.connorgarvey.com/blog/?p=105Injecting values for static constants in Spring

      【讨论】:

        【解决方案4】:

        Bean 不能是静态类。它们需要由 Spring 在内部实例化。并且静态类显然不能被实例化。改用这个:

        public class DefaultPaymentGateway {
        
            private static String paymentGatewayName = "VPN";
        
            public String getPaymentGatewayName() {
                return paymentGatewayName;
            }
        
            public void setPaymentGatewayName(String paymentGatewayName) {
                paymentGatewayName = paymentGatewayName;
            }
        
        }
        

        您不应该在 getter/setter 方法中做太多事情。 Getter 应该只返回属性,而 setter 应该只设置它。从他们那里调用其他 getter/setter 会带来麻烦。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-06-24
          • 2017-08-20
          • 2013-10-06
          • 2015-06-29
          • 2018-04-07
          • 2017-09-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多