Spring Roo, and mixing xml and annotated dependency injection of a Property

I used Spring Roo (with Spring 3.0) to create a simple project with a few domain objects and controllers. I wanted to experiment with using the @Component annotation and autowiring, but was having severe problems trying to autowire a String value (the url of a service) into my @Component managed bean, the string being contained in the xml of the application context. After searching several blogs, this is what I found:

  1. it is not possible to autowire a primitive value using annotations
  2. it WAS not possible before Spring 3, now you can do it with Spring Expression Language (spEL)

Here was my next to last attempt:

webmvc-config.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
				
	<!-- The controllers are autodetected POJOs labeled with the @Controller annotation. 
	<context:component-scan base-package="org.tcl" use-default-filters="false">
		<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
	</context:component-scan> -->

	<!-- The controllers are autodetected POJOs labeled with the @Controller annotation. -->
	<context:component-scan base-package="org.tcl" />
	<context:annotation-config/>
	
	<!-- Turns on support for mapping requests to Spring MVC @Controller methods
	     Also registers default Formatters and Validators for use across all @Controllers -->
	<mvc:annotation-driven/>

        <util:properties id="appProperties" location="classpath:/app.properties"/> 
...

TclApiService.java:

package org.tcl.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class TclApiService implements ApiService {

	@Value("#{appProperties['tclApiUrl']}") String apiUrl;
	
	@Override
	public ApiResponse call() {
		return null; //breakpoint here, just to check out the value of the apiUrl property 
	}

	public void setApiUrl(String apiUrl) {
		this.apiUrl = apiUrl;
	}

}

app.properties:

tclApiUrl=http://www.mydomain.org/api/courses

No matter WHAT I tried, the tc server startup would fail with errors such as:

No matching bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}


or, in the case of my final spEL attempt:

Field or property 'appProperties' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext'

Turns out, this is what is happening:
Since the <context:component-scan> tag occurs before the “appProperties” bean definition in webmvc-config.xml, the bean definition is not available when the @Component-ized class is being constructed. The fix is simple, just move the “appProperties” bean definition above any <context:component-scan> tag. In Roo, keep in mind, at least in my case, that there were actually 2 <context:component-scan> tags, one in applicationContext.xml and one in webmvc-config.xml. Putting my properties bean definition above the one in applicationContext.xml solved the problem. Tc Server now started successfully and the property was populated in my @Component class.

Nowhere in official spring documentation could I find the stipulation that it actually matters where the <context:component-scan> tag is placed. Initially I thought that spring might maintain a map of unresolved dependencies which are satisfied in a round robin fashion, but nope, the xml dependencies are resolved first, then the annotated ones – at least in this simple case.