Skip to content

Support injection against setter methods with non-void return types [SPR-8079] #12734

Closed
@spring-projects-issues

Description

@spring-projects-issues

Chris Beams opened SPR-8079 and commented

The JavaBeans specification considers property 'write methods' (setters) to be those:

  1. starting with the string 'set', followed by the capitalized name of the property. (setFoo(Foo), setBar(Bar))
  2. accepting a single argument that matches the return type of the 'read method' (getter), if any. (public Foo getFoo(), public void setFoo(Foo)
  3. having a void return type.

These requirements are reflected in the implementation of the static java.beans.Introspector#getBeanInfo(Class) method, which Spring uses to determine what properties are available for injection (see org.springframework.beans.CachedIntrospectionResults.

The third constraint above poses a problem in certain cases, particularly where a 'builder-style' API is being used -- one that allows for method chaining setters by returning the this reference of the builder object.

Such builder-style objects are convenient for use when configuring Spring beans programmatically within @Configuration class @Bean methods, for example, but if one attempts to use them as <bean/> definitions within a Spring XML file, the container will throw a NotWritablePropertyException. This is not because Spring is incapable of calling the non-standard setter style, but rather because Introspector#getBeanInfo() never notices the non-standard setter in the first place, and any subsequent call to BeanInfo#getPropertyDescriptors() will fail to report its existence.

For this reason, we will introduce a decorator for the BeanInfo object returned from Introspector#getBeanInfo() that takes one more pass against the specified class, looking for any setter methods with non-void return types. Calls to the decorated BeanInfo type will faithfully report these methods, and Spring's injection facilities will operate normally from there.

It is important that:

  • this work play nicely with the existing decoration approach in GenericTypeAwarePropertyDescriptor.
  • non-void returning setter methods are detected even if there is no matching getter method declared. This is a common scenario within framework classes.

While this is a generally useful addition to the framework, it is getting priority now in order to support the work described in #12076 -- specifically #12721, which deals with refactoring Spring's *SessionFactoryBean types to extend the new @Configuration-friendly *SessionFactoryBuilder types. When doing this, the signature of the FactoryBeans' setter methods changes to non-void return types and causes the issue described above. Implementing this new feature will eliminate this problem.


Issue Links:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions