Spring @Value註解失敗

Spring 版本 3.0.5.Release

@Value註解有兩種形式:

1、@Value("${}")
如果只在application-context.xml中註冊配置文件:

	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="ignoreUnresolvablePlaceholders" value="true" />
		<property name="locations">
			<list>
				<value>classpath:base.properties</value>
				<value>classpath:web.properties</value>
			</list>
		</property>
	</bean>
在xxx-servlet.xml中不註冊改配置文件,此時@Controller註解的類無法使用@Value("${}")注入常量。(也即配置文件是在ContextLoaderListener初始化時加載。通常@Controller是由DispatcherServlet進行掃描並實例化的)。

這種情況是ContextLoaderListener初始化加載配置文件發生在前,而DispatcherServlet掃描並實例化Controller類是發生在後,這個時候爲什麼@Value註解失敗?

如果我在xxx-servlet.xml中添加上下面的配置@Controller就可以直接使用@Value("${}")注入了。(也即在DispatcherServlet中也進行配置文件加載)

	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="ignoreUnresolvablePlaceholders" value="true" />
		<property name="locations">
			<list>
				<value>classpath:base.properties</value>
				<value>classpath:web.properties</value>
			</list>
		</property>
	</bean>

2、@Value("#{webProperties['properties.name']}")
只在application-context.xml中註冊配置文件:
<util:properties id="webProperties" location="classpath:web.properties" />
此時,@Controller和其它的@Component都可以使用@Value("#{webProperties['properties.name']}")注入常量。
ContextLoaderListener和DispatcherServlet實例化的對象都能用這種方式注入常量。

現象已經明瞭,但是爲什麼會出現這種情況還有待深究,特別是@Value("${}")的形式,似乎ContextLoaderListener加載的配置文件對DispatcherServlet不可見。


檢測@Value注入問題最好先排查下bean是否被多次掃描,實例化了多次。然後在@PostConstruct中打印出@Value常量。我遇到的情況是ContextLoaderListener和DispatcherServlet都掃描並實例化了@Controller註解類,但是DispatcherServlet實例化的類@Value注入常量失敗,ContextLoaderListener實例化的類@Value注入常量成功,但是ContextLoaderListener實例化早,被覆蓋掉了。最終導致實例化的@Controller類是沒有注入常量的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章