TA的每日心情  | 开心 2021-12-13 21:45 | 
|---|
 
  签到天数: 15 天 [LV.4]偶尔看看III  
 | 
 
| 
 
 在把某项技术整合到Spring中的时候,我们时常会发现报如下错误:  
 org.springframework.beans.factory.BeanCreationException: Error creating bean with name "loginController": Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field:  
   
查阅了很多方法 都没有实际的解决 后来才发现是因为spring的配置文件没有放到  
<listener> 
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
 </listener>  
的 <context-param>中造成的:  
具体有如下两种解决方案:  
1.把所有的XML配置文件放到<param-value>中,一般来说XML后面的英文逗号可加也可不加(一般系统能识别):  
  
- <listener>
 -     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 -   </listener>
 -   
 -   <context-param>
 -     <param-name>contextConfigLocation</param-name>
 -  
 -     <param-value>
 -     classpath:spring-dao.xml,
 -    classpath:spring-service.xml,
 -     classpath:springmvc-servlet.xml
 -     </param-value>
 -   </context-param>
 
  复制代码 
  
    
2.用*来匹配有一定相同点的XML文件 并放到<param-value>中,这在一定程度上减少了代码的冗余:  
  
-  <listener>
 -     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 -   </listener>
 -   
 -   <context-param>
 -     <param-name>contextConfigLocation</param-name>
 -     
 -     <param-value>classpath*:spring-*.xml</param-value>
 -     
 -   </context-param>
 
  复制代码 
  
 原理介绍:  
1, 在web.xml中定义 contextConfigLocation参数.spring会使用这个参数加载.所有逗号分割的xml.如果没有这个参数,spring默认加载web-inf/applicationContext.xml文件.  
<context-param> 
<param-name>contextConfigLocation</param-name> 
<param-value> 
classpath*:conf/spring/applicationContext_core*.xml, 
classpath*:conf/spring/applicationContext_dict*.xml, 
classpath*:conf/spring/applicationContext_hibernate.xml, 
classpath*:conf/spring/applicationContext_staff*.xml, 
classpath*:conf/spring/applicationContext_security.xml 
classpath*:conf/spring/applicationContext_modules*.xml 
classpath*:conf/spring/applicationContext_cti*.xml 
classpath*:conf/spring/applicationContext_apm*.xml 
</param-value> 
</context-param>  
 
contextConfigLocation 参数定义了要装入的 Spring 配置文件。原理说明如下: 
、利用ServletContextListener 实现。 
Spring 提供ServletContextListener 的一个实现类ContextLoaderListener ,该类可以作 
为listener 使用,它会在创建时自动查找WEB-INF/ 下的applicationContext.xrnl 文件。因 
此,如果只有一个配置文件,并且文件名为applicationContext.xml ,则只需在web.xml 
文件中增加如下代码即可: 
<listener> 
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
如果有多个配置文件需要载入,则考虑使用<context-para即元素来确定配置文件的 
文件名。由于ContextLoaderListener加载时,会查找名为contextConfigLocation的参数。 
因此,配置context-param时参数名字应该是contextConfigLocation。 
带多个配置文件的web.xml 文件如下: 
<1-- XML 文件的文件头二〉 
<?xml version="l.O" encoding="工80-8859-1"?> 
< 1-- web.xm1 文件的DTD 等信息一〉 
<!DOCTYPE web-app 
PUBLIC "-//Sun Microsystems. 工口c.//DTD Web Application 2.3//EN" 
""http://java.sun.com/dtd/web-app_2_3.dtd""> 
<web-app> 
<!一确定多个配置文件> 
<context-param> 
<1-- 参数名为contextConfigLocation…〉 
<param-name>contextConfigLocation</param-name> 
<!一多个配置文件之间以,隔开二〉 
<param-value>/WEB-工NF/daoContext.xml./WEB-INF/application 
Context.xml</param-value> 
</context-param> 
<!-- 采用listener创建Applicat工onContext 实例--> 
<listener> 
<listener-class>org.spr工ngframework.web.context.ContextLoader 
Listener</listener-class> 
</listener> 
</web-app> 
如果没有contextConfigLocation 指定配置文件,则Spring 自动查找application 
Context. xrnl 配置文件。如果有contextConfigLocation,则利用该参数确定的配置文件。 
该参数指定的一个字符串, Spring 的ContextLoaderListener 负责将该字符串分解成多个 
配置文件,逗号","、空格" "及分号";"都可作为字符串的分割符。 
如果既没有applicationContext. xrnl 文件,也没有使用contextConfigLocation参数确 
定配置文件,或者contextConfigLocation确定的配置文件不存在。都将导致Spring 无法 
加载配置文件或无法正常创建ApplicationContext 实例 
 
配置一个spring为加载而设置的servlet可以达到同样效果. 
采用load-on-startup Servlet 实现。 
Spring 提供了一个特殊的Servllet 类: ContextLoaderServlet。该Servlet 在启动时,会 
自动查找WEB-IN日下的applicationContext. xml 文件。 
当然,为了让ContextLoaderServlet 随应用启动而启动,应将此Servlet 配置成 
load-on-startup 的Servleto load-on-startup 的值小一点比较合适,因为要保证Application 
Context 优先创建。如果只有一个配置文件,并且文件名为applicationContext. xml ,则在 
web.xml 文件中增加如下代码即可: 
<servlet> 
<servlet-name>context</servlet口-arne> 
<servlet-class>org.springframework.web.context.ContextLoaderServlet</ 
servlet-class> 
<load-on-startup>l</load-o 口-startup> 
</servlet> 
 
。带多个配置文件的web且nl 文件如下: 
<!-- XML 文件的文件头--> 
<?xml version="1.0" encoding="工SO-8859-1"?> 
<! -- web.xml 文件的DTD 等信息→ 
<!DOCTYPE web-app 
PUBLIC "-//Sun Microsystems , 工口c.//DTD Web Application 2.3//EN" 
""http://java.sun.com/dtd/web-app_2_3.dtd""> 
<web-app> 
<"一确定多个配置文件一> 
<context-param> 
<!-- 参数名为contextConfigLocation--> 
<param-name>contextConfigLocation</param-name> 
<!-- 多个配置文件之间以,隔开一〉 
<param-value>/WEB-工NF/daoContext.xml, !WEB-工NF/applicationContext. 
xml</param-value> 
</context-param> 
<!一采用load-on-startup Servlet 创建Applicat工onContext 实例一〉 
<servlet> 
<servlet-narne>context</servlet-narne> 
<servlet-class>org.springframework.web.context.ContextLoader 
Servlet</servlet-class> 
<!一下面值小一点比较合适,会优先加载一〉 
<load-on-startup>l</load-on-startup> 
</servlet> 
</web-app> 
 
 
2, 使用匹配符 
 
<context-param> 
<param-name>contextConfigLocation</param-name> 
<param-value>/WEB-INF/applicationContext*.xml</param-value> 
</context-param> 
 
比 如说用到Hibernate,则把hibernate相关的配置放在applicationContext-hibernate.xml这一个文件,而一 些全局相关的信息则放在applicationContext.xml,其他的配置类似.这样就可以加载了,不必写用空格或是逗号分开!  
 
 
3, 如果使用struts加载多个spring配置文件.下面这个配置的其实也是contextConfigLocation变量. 
 
struts-config.xml里面加这个 
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> 
<set-property property="contextConfigLocation"  
value="/WEB-INF/applicationContext.xml, 
/WEB-INF/action-servlet.xml,,,,,,,"/> 
 
4,如果是非j2ee应用直接程序加载. 
 
ApplicationContext act = new ClassPathXmlApplicationContext(new String[]{"bean1.xml","bean2.xml"}); 
 
BeanDefinitionRegistry reg = new DefaultListableBeanFactory(); 
 
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(reg); 
 
reader.loadBeanDefinitions(new ClassPathResource("bean1.xml")); 
 
reader.loadBeanDefinitions(new ClassPathResource("bean2.xml")); 
 
  
BeanFactory bf = (BeanFactory)reg; |   
 
 
 
 |