NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.web.servlet.view.InternalResourceViewResolver' available
问题描述:
项目中需要配置多个视图解析器,所以使用ContentNegotiatingViewResolver来处理,在其内部设置了FreeMarkerViewResolver 、InternalResourceViewResolver两个视图解析器,同时还有一个默认的defaultViews。
在测试类中,想要获取InternalResourceViewResolver类,会报错说没有定义InternalResourceViewResolver这个bean,找不到。
直接上图上代码:
applicationContext.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | < bean id="contentViewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> < property name="viewResolvers"> < list > < bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> < property name="order" value="1" /> < property name="requestContextAttribute" value="request" /> < property name="cache" value="false" /> < property name="prefix" value="" /> < property name="suffix" value=".ftl" /> < property name="contentType" value="text/html; charset=utf-8" /> </ bean > < bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> < property name="prefix" value="/" /> < property name="suffix" value=".jsp" /> < property name="order" value="2"/> </ bean > </ list > </ property > < property name="defaultViews"> < list > < bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"> </ bean > </ list > </ property > </ bean > |
测试类:
1 2 3 4 5 | String conf = "applicationContext.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(conf); InternalResourceViewResolver inter = ctx.getBean(InternalResourceViewResolver.class); System.out.println("inter: " + inter); |
报错信息:
1 2 3 4 5 | Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.web.servlet.view.InternalResourceViewResolver' available at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:353) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1090) at com.quanwc.blog.controller.UserController.main(UserController.java:39) |
原因分析:
1 2 3 4 5 | ContentNegotiatingViewResolver content = ctx.getBean(ContentNegotiatingViewResolver.class); System.out.println("content: " + content); //可以获取到ContentNegotiatingViewResolver这个bean InternalResourceViewResolver inter = ctx.getBean(InternalResourceViewResolver.class); System.out.println("inter: " + inter); //报错,无法获取到InternalResourceViewResolver这个bean |
结果:
外部的ContentNegotiatingViewResolver bean可以获取到,但是其内部的InternalResourceViewResolver却无法获取到
原因:
spring在创建ContentNegotiatingViewResolver 的时候,会将InternalResourceViewResolver创建出来,并注入给viewResolvers这个属性; 在这个过程中spring并没有将创建出的InternalResourceViewResolver这个bean对象保存一份到自己的容器中。
也就说说,id为viewResolver的bean只服务于Id为contentViewResolver的这个bean。
我们可以将 InternalResourceViewResolver声明在外部的一个bean中,在ContentNegotiatingViewResolver 内部使用ref对其进行引用: <ref bean="viewResolver2"/>
参考链接:http://blog.sina.com.cn/s/blog_635675db01018miz.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步