Search code examples
javaspringannotationsautowiredxml-configuration

Spring: apply @Autowired to property to eliminate setter


My understanding about the @Autowired annotation applying on a property of a bean is that by doing that we can eliminate the setter method. This seems valid when we choose to annotation based configuration: we just create a bean annotated with @Component and annotate @Autowired to its property of interest.

However I failed to do the same when I tested the idea using xml based configuration.

Here is what I put in the bean class:

@Autowired
private String message2;

public String getMessage2() {
    return message2;
}

In the xml file:

<bean id="testBean" class="TestBean">
    <property name="message2" value="Hello world!"/>
</bean> 

the IDE complained "can't resolve the property" and failed to compile. Maybe using @Autowired with xml configuration is an odd marriage that is disallowed?

Anyone care to help me on this might-be-silly question?


Solution

  • If you don't want the setter, then get rid of the <property> element in your TestBean bean definition. That property requires that a setter be available to set the property. Because it's missing, if you actually tried to load the XML configuration, with a ClassPathXmlApplicationContext for example, you'd get this error

    Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property message2 of bean class [org.example.TestBean]: Bean property message2 is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

    After removing <property>, declare an appropriate bean to inject

    <bean id="message2" class="java.lang.String">
      <constructor-arg value="Helllo world!"/>
    </bean>
    

    You'll also need

    <context:annotation-config />
    

    to register the AutowiredAnnotationBeanPostProcessor that handles processing of @Autowired.


    Note that declaring a String bean is awkward. You'd be better served by using the <property> or some property resolution mechanism that pulls the value from a config file and assigns it through a @Value annotated field.

    @Value("${config.message2}")
    private String message2;