Spring和SpringMVC父子容器关系所引发的血案

一、背景

最近在使用工具类实现将数据库中的数据批量导入到Solr索引库的时候,使用单元测试提示:

java.lang.IllegalStateException: Failed to load ApplicationContext

在解决问题的过程中,偶然发现了Spring和SpringMVC是有父子容器关系的,正是由于这种父子容器关系的存在,导致了问题的存在。

二、错误重现

下面是我的测试类:

public class SolrUtil {

    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private SolrTemplate solrTemplate;

    //实现将数据库中的数据批量导入到Solr索引库中
    @Test
    public void importGoodsData() {
        List<Goods> list = goodsDao.findAll();
        System.out.println("===数据库中的数据===");
        for(Goods goods : list) {
            System.out.println(goods.getId()+" "+goods.getTitle());
        }
        solrTemplate.saveBeans(list);
        solrTemplate.commit();
        System.out.println("===结束===");
    } 

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/*.xml");
//      context = new ClassPathXmlApplicationContext("classpath:spring/*.xml");
        SolrUtil solrUtil = (SolrUtil) context.getBean("solrUtil");
        solrUtil.importGoodsData();
    }

}

?
我开始没有使用junit进行单元测试,直接执行的main方法。注意我加载的配置文件,先看下我的目录结构:
?

?
可以看出我把SpringMVC的配置文件也加载进来了。一开始我以为是jar包冲突,换了jar包的版本,后来发现tomcat启动正常,执行其他对数据库的操作也没有问题,我就排除了这方面的问题。然后我突然想到可以用junit进行单元测试,于是有了下面的代码
?

@Component
@ContextConfiguration(locations="classpath:spring/*.xml")
@RunWith(SpringJUnit4Cla***unner.class)

可以看到我使用了@ContextConfiguration注解,这个注解的作用是啥呢?

@ContextConfiguration Spring整合JUnit4测试时,使用注解引入多个配置文件

这时候我就考虑到了是不是通配符写错的原因呢?于是有了下面这行代码

@ContextConfiguration(locations= {"classpath:spring/spring-solr.xml","classpath:spring/spring-service.xml","classpath:spring/spring-dao.xml","classpath:spring/spring-shiro.xml",})

碰巧我没有加载SpringMVC的配置文件,于是问题就解决了。

三、原因分析

?在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的。Spring和SpringMVC的容器存在父子关系,即Spring是父容器,SpringMVC是其子容器,子容器可以访问父容器的对象,父容器不能访问子容器的类。另外Spring会把使用了@Component注解的类,并且将它们自动注册到容器中。这也是我们为什么不在Spring容器管理controller的原因,即:一定要把不同的bean放到不同的容器中管理。
?

四、后记

?
折腾了一天,终于解决了这个问题,特此记录一下,-_- 。

原文地址:http://blog.51cto.com/13416247/2309590

时间: 2024-10-03 14:03:02

Spring和SpringMVC父子容器关系所引发的血案的相关文章

Spring和SpringMVC父子容器关系初窥

一.背景 最近由于项目的包扫描出现了问题,在解决问题的过程中,偶然发现了Spring和SpringMVC是有父子容器关系的,而且正是因为这个才往往会出现包扫描的问题,我们在此来分析和理解Spring和SpringMVC的父子容器关系并且给出Spring和SpringMVC配置文件中包扫描的官方推荐方式. 二.概念理解和知识铺垫 在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的,而在一个项目中,容器不一定只有一个,Spring中可以包括多个容器,而且容器有上

Spring与SpringMVC的容器关系分析

Spring和SpringMVC作为Bean管理容器和MVC层的默认框架,已被众多WEB应用采用,而实际使用时,由于有了强大的注解功能,很多基于XML的配置方式已经被替代,但是在实际项目中,同时配置Spring和SpringMVC时会出现一些奇怪的异常,比如Bean被多次加载,多次实例化,或者依赖注入时,Bean不能被自动注入,但是明明你已经将该Bean注册了的.找原因还是要看问题的根源,我们从容器说起. 在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的,

Spring 和SpringMVC 的父子容器关系

Spring和SpringMVC作为Bean管理容器和MVC层的默认框架,已被众多WEB应用采用,而实际使用时,由于有了强大的注解功能,很多基于XML的配置方式已经被替代,但是在实际项目中,同时配置Spring和SpringMVC时会出现一些奇怪的异常,比如Bean被多次加载,多次实例化,或者依赖注入时,Bean不能被自动注入,但是明明你已经将该Bean注册了的.找原因还是要看问题的根源,我们从容器说起. 在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的,

Spring和SpringMVC父子的容器之道---[上篇]

昨天,给数据组写接口,不小心掉进坑里挣扎了半天,最后发现是spring和springmvc它们虽是父子但并不和谐,于是在此一记. Spring和SpringMVC作为Bean管理容器和MVC层的默认框架,已被众多WEB应用采用,而在实际开发中,由于有了强大的注解功能,很多基于XML的配置方式已经被替代,但在实际项目中,我们经常会同时配置Spring和SpringMVC的配置文件,分层来管理它们,但是有时候就会出现那么一些奇怪的异常,一旦进坑,让你无法自拔,就在昨天给数据组写接口时,我进坑了,就在

SpringMvc父子容器

使用监听器listener来加载spring的配置文件:如下 <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-beans.xml</param-value> </context-param> <listener> <listener-class>org.springframe

Spring与SpringMVC的父子容器关系

和Java的多态很类似,在子类中,可以定义service,dao,controller(这个必须是springmvc容器对象),也可以把service和dao定义在spring容器中,但是要注意的是,这样做的话在父类容器不能去注入子类中的controller对象 原文地址:https://www.cnblogs.com/Booker808-java/p/8322593.html

Spring和SpringMVC的关系

1.Spring和SpringMVC是父子容器关系. 2.Spring整体框架的核心思想是容器,用来管理bean的生命周期,而一个项目中会包含很多容器,并且它们分上下层关系,目前最常用的一个场景是在一个项目中导入Spring和SpringMVC框架,而Spring和SpringMVC其实就是两个容器,Spring是父容器,SpringMVC是子容器,Spring父容器中注册的Bean对SpringMVC子容器是可见的,反之则不行. 3.按照官方文档推荐,根据不同的业务模块来划分不同的容器中注册不

Spring中父子容器的实现实例

Spring中父子容器的实现实例Spring的父子容器可以通过ConfigurableApplicationContext或ConfigurableBeanFactory来实现,这两个接口中分别有setParent及setParentBeanFactory方法,可以与当前的子容器进行父子容器关联,这个时候子容器就可以引用父容器中的bean,但是父容器是不能够引用子容器中的bean的,并且各个子容器中定义的bean是互不可见的,这样也可以避免因为不同的插件定义了相同的bean而带来的麻烦.应用场景

Spring以及SPringmvc相关问题: ServletContext -父子容器

总结如下: 明确了Servlet规范中ServletContext的作用和意义.此外明确一个Tomcat中多个web应用,每个人web应用有唯一的一个ServletContext(全局上下文).[例子见:同一tomcat多个应用session问题] 这个ServletContext 对应JSP中内置对象javax.servlet.jsp.ServletContext(作用于application全局级) 明确Spring(Spring.context包定义)上下文 ApplicationCont