【问题标题】:Getting org.springframework.beans.NotWritablePropertyException获取 org.springframework.beans.NotWritablePropertyException
【发布时间】:2022-02-06 08:31:57
【问题描述】:

我目前正在学习 Spring。我在依赖注入主题中,我正在尝试通过 DI 将 Reference 对象注入到 setter 中。但我面临一个问题。

Client.java

package bean.driver;

import bean.Car;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Client {

    public static void main(String [] args)
    {
        String files[] = new String[]{"engine.xml","car.xml"};
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(files);

        Car car = (Car) applicationContext.getBean("car");
        //car.printdata();
        car.printcardata();

    }
}

汽车.java

package bean;

public class Car {

    private String carname;
    private Engine engine;
    private int cost;
    private int yearofRelease;
    private int maxspeed;
    private Inventory inventory;
    private String engineversion;


    /*Car(String carname, Engine engine)
    {
        this.carname = carname;
        this.engine = engine;
    }*/
    Car(String name,Engine engine,Inventory inventory, int maxspeed)
    {
        this.carname = name;
        this.maxspeed = maxspeed;
        this.engine = engine;
        this.inventory = inventory;
    }

    public void setCost(int cost)
    {
        this.cost = cost;
    }
    public void setYearofRelease(int yearofRelease)
    {
        this.yearofRelease = yearofRelease;
        System.out.println(engine.getEngineversion());
    }
    /*public void setEngine(Engine engine2)
    {
        this.engineversion = engine2.getEngineversion();
    }
    public String getEngineversion()
    {
        return engineversion;
    }*/

    public void setEngineVersion(Engine engine)
    {
        this.engineversion = engine.getEngineversion();
    }
    public void printdata()
    {
        System.out.println(carname + " "+ engine.getModel() +" "+cost+" "+yearofRelease);
    }

    public void printcardata()
    {
        System.out.println("Carname:-"+carname+"\n"+"Cost:-"+cost+"\n"+"MaxSpeed:-"+maxspeed+"\n"+
                "Year of Release:-"+yearofRelease+"\n"+"Engine model:-"+engine.getModel()+"\n"+
                "No of Units:-"+inventory.getNoofinitalunits()+"\n"+"Engine Version:-"+engineversion);
    }

}

Engine.java

package bean;

public class Engine {

    private String model;
    private String engineversion;

    Engine(String model)
    {
        this.model = model;
    }

    public void setEngineversion(String engineversion) {
        this.engineversion = engineversion;
    }

    public String getModel()
    {
        return model;
    }

    public String getEngineversion()
    {
        return engineversion;
    }
}

汽车.xml

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
        "https://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>


    <bean id="car" class="bean.Car">

        <!--dependecy injection through constructor of secondary type-->
         <constructor-arg ref="engine"/><!-- we are passing object as a reference -->

         <constructor-arg>
         <ref bean="inventory"></ref>
        </constructor-arg><!-- passing object as a refernece -->

        <!-- pass object as a value -->

        <!--<constructor-arg>
            <bean class="bean.Engine">
                <constructor-arg>
                    <value>S10</value></constructor-arg>
            </bean>
        </constructor-arg>-->

        <!--dependency injection through constructor of primary type-->
        <constructor-arg value="Suzuki"/>
        <constructor-arg>
            <value>230</value>
        </constructor-arg>

        <!--dependency injection through setters of primary type-->
        <property name="cost" value="10"/>
        <property name="yearofRelease">
            <value>1994</value>
        </property>

        <!--dependecy injection through setter of secondary type-->

        <property name="engine" ref="engine"></property>


    </bean>

    <bean id="inventory" class="bean.Inventory">
        <constructor-arg>
            <value>1000</value>
        </constructor-arg>
    </bean>

    <bean id="engine2" class="bean.Engine">
        <constructor-arg value="S88"/>
        <property name="engineversion" value="V11"/>
    </bean>
</beans>

engine.xml

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
        "https://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>

    <bean id="engine" class="bean.Engine">

        <constructor-arg value="S88"/>
        <property name="engineversion" value="V11"/>


    </bean>

    <bean id="engine2" class="bean.Engine">

        <constructor-arg value="S88"/>
        <property name="engineversion" value="V11"/>


    </bean>

</beans>

错误

"C:\Program Files\Java\jdk-15.0.1\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.2.3\lib\idea_rt.jar=51693:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.2.3\bin" -Dfile.encoding=UTF-8 -classpath D:\Spring-2\target\classes;C:\Users\chris\Downloads\spring-beans-5.3.15.jar;C:\Users\chris\Downloads\spring-context-5.3.15.jar;C:\Users\chris\Downloads\spring-core-5.3.15.jar;C:\Users\chris\Downloads\spring-expression-5.3.15.jar;C:\Users\chris\Downloads\commons-logging-1.2.jar bean.driver.Client
V11
Feb 06, 2022 1:53:20 PM org.springframework.context.support.ClassPathXmlApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'car' defined in class path resource [car.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'engine' of bean class [bean.Car]: Bean property 'engine' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'car' defined in class path resource [car.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'engine' of bean class [bean.Car]: Bean property 'engine' 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:1744)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1452)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:95)
    at bean.driver.Client.main(Client.java:12)
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'engine' of bean class [bean.Car]: Bean property 'engine' 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.createNotWritablePropertyException(BeanWrapperImpl.java:243)
    at org.springframework.beans.AbstractNestablePropertyAccessor.processLocalProperty(AbstractNestablePropertyAccessor.java:432)
    at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:278)
    at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:266)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:104)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:79)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1740)
    

Process finished with exit code 1

查看属性名称是引擎,并且在我提到的 xml 文档中仅作为引擎。但仍然收到错误。

【问题讨论】:

  • 不要再使用旧的xml配置。仅使用新的基于注释的方式。
  • 感谢您的建议,但不知道为什么会出现上述错误。
  • Car 中看不到engine 的任何setter setter 的参数类型是否与getter 的返回类型匹配?
  • 哦,好的,请告诉我,如果我们设置了 ,那么会在 spring 中寻找 setengine()。它是否区分大小写,就像它是否也接受 setEngine() 一样?感谢您的帮助。
  • 必须是setEngine。由于 java 命名约定。

标签: java spring spring-boot


【解决方案1】:

Xml 配置是旧的,最好阅读新的 xml 配置。 您应该像下面的代码一样更改您的 xml 文件。

汽车.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
        xmlns:beans="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.xsd">

    <beans:bean id="car" class="com.example.stackoverfollw.Car">

        <beans:constructor-arg index="0" value="220"/>
        <beans:constructor-arg index="1" ref="engine"/>
        <beans:constructor-arg index="2" ref="inventory"/>
        <beans:constructor-arg index="3" value="650"/>
    </beans:bean>


    <beans:bean id="engine" class="com.example.stackoverfollw.Engine">
        <beans:constructor-arg value="V11"/>
    </beans:bean>

    <beans:bean id="inventory" class="com.example.stackoverfollw.Inventory">
    </beans:bean>


</beans:beans>

Engine.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
        xmlns:beans="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.xsd">

    <beans:bean id="engine" class="com.example.stackoverfollw.Engine">
        <beans:constructor-arg value="v22"/>
    </beans:bean>


</beans:beans>

更多关于 bean 的信息

【讨论】:

  • 感谢您的建议。但是你能告诉我为什么我得到上述错误。我正在尝试设置值,但未设置最后一个值“引擎”对象。
  • Xml 配置是旧的,最好阅读一下新的 xml 配置。 你的意思是新的annotations based?
猜你喜欢
  • 2011-07-02
  • 2019-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
相关资源
最近更新 更多