创建bean时出错

时间:2013-01-02 05:53:17

标签: java spring junit javabeans

这是我得到的错误跟踪:

 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;
}

}

这就是bean:

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

问题是什么?

4 个答案:

答案 0 :(得分: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属性。

除去

<property name="paymentGatewayName" value="VPC"></property>并将其设置在您的课程中。

private static String paymentGatewayName="VPC";

或使其不是静态的。

答案 1 :(得分:1)

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

解决方法

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

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

答案 2 :(得分:1)

Beans不能是静态类。它们需要由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就是麻烦。

答案 3 :(得分:0)

不要使用静态setter,删除setter中的static关键字