Spring父容器:
web.xml初始化:
<!-- 启动spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext*.xml</param-value> </context-param> <!-- 加载contextConfigLocation --> <listener> <!-- spring会初始化一个启动上下文,这个上下文被称为根上下文,即WebApplicationContext, 这是一个接口类,确切的说,其实际的实现类是XmlWebApplicationContext。 这个就是spring的IoC容器,其对应的Bean定义的配置由web.xml中的context-param标签指定 --> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
Spring子容器:
web.xml初始化:
<!-- 加载Springmvc --> <servlet> <servlet-name>manage-servlet</servlet-name> <!-- 建立自己的IoC上下文,用以持有spring mvc相关的bean --> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/manage-servlet.xml</param-value> </init-param> <!-- 随容器自动启动完成初始化 --> <load-on-startup>1</load-on-startup> </servlet>
- SpringMVC子容器可以访问Spring父容器:可以直接注入父类bean到子类容器中
- Spring父容器不可以访问SpringMVC子容器
然而使用使用spring自带的占位符替换功能:org.springframework.beans.factory.config.PropertyPlaceholderConfigurer加载properties文件时候,子容器并不能访问到父容器中的bean,配置如下
applicationContext.xml <!-- 使用spring自带的占位符替换功能 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <!-- 允许JVM参数覆盖 --> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <!-- 忽略没有找到的资源文件 --> <property name="ignoreResourceNotFound" value="true" /> <!-- 配置资源文件 --> <property name="locations"> <list> <value>classpath:jdbc.properties</value> <value>classpath:evn.properties</value> </list> </property> </bean>
分析:
使用@PostConstruct 将对象注入打印到控制台,发现有两次初始化,一次是父容器初始,第二次是子容器初始时候,第一次能正常取到properties对象,第二次时不能获取到值
//子容器的直接访问 @Value("${REPOSITORY_PATH}")//properties文件中 REPOSITORY_PATH=D:\\home\\download private String REPOSITORY_PATH; @PostConstruct public void log() { System.out.println("初始化==================" + REPOSITORY_PATH + "=========="); }
解决方法:
重新写一个类将xml的中bean注入到一个父容器中的一个service类,供其他子容器调用
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service public class PropertieService { @Value("${REPOSITORY_PATH}") public String REPOSITORY_PATH; @Value("${IMAGE_BASE_URL}") public String IMAGE_BASE_URL; }