是否可以使Spring忽略不可写或具有无效setter方法的bean属性

时间:2013-12-06 18:46:48

标签: java spring

有没有办法让Spring在下面的情况下不抛出异常?

<bean id="myMain" class="pak.Main">
  <property name="name" value="myName"/>
  <property name="age" value="100"/>
  <property name="human" value="true"/>
</bean>


public class Main {
  private String name;
  private Integer age;

  public void setName(String name) {
    this.name = name;
  }

  public void setAge(Integer age) {
    this.age = age;
  }

  public static void main(String[] args) {
     new ClassPathXmlApplicationContext("beans.xml")
        .getBean("myMain", Main.class);
  }
}

抛出

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myMain' defined in class path resource [beans.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'human' of bean class [pak.Main]: Bean property 'human' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

1 个答案:

答案 0 :(得分:3)

想象一下我的意料是答案是肯定的。

输入InstantiationAwareBeanPostProcessor ...或更具体(更容易实施)InstantiationAwareBeanPostProcessorAdapter

在bean的属性实例化之前调用此bean后期处理器。您可以覆盖的方法是postProcessPropertyValues

此方法提供有关它的bean及其属性的信息。然后,您可以以任何您认为合适的方式修改bean的属性。具体来说,有一个PropertyValue.setOptional(boolean)方法看起来很有意思。

使用您的场景将一个快速示例放在一起,定义一个类:

MyInstantiationAwareBeanPostProcessor.java:

import java.beans.PropertyDescriptor;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.stereotype.Component;

@Component
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        if (bean instanceof pak.Main) {
            for (PropertyValue pv : pvs.getPropertyValues()) {
                if ("human".equals(pv.getName())) {
                    pv.setOptional(true);
                }
            }
        }
        return pvs;
    }

}

然后确保以下行位于您的上下文中:

<bean id="instantiationAwarePP" class="pak.MyInstantiationAwareBeanPostProcessor"/>

你是金色的。

P.S。您可能还需要在上下文中定义<context:annotation-config />,以便后处理器自动注册...但我不记得是否有必要。