問題描述:
項目中需要配置多個視圖解析器,所以使用ContentNegotiatingViewResolver來處理,在其內部設置了FreeMarkerViewResolver 、InternalResourceViewResolver兩個視圖解析器,同時還有一個默認的defaultViews。
在測試類中,想要獲取InternalResourceViewResolver類,會報錯說沒有定義InternalResourceViewResolver這個bean,找不到。
直接上圖上代碼:
applicationContext.xml:
<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>
測試類:
String conf = "applicationContext.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(conf);
InternalResourceViewResolver inter = ctx.getBean(InternalResourceViewResolver.class);
System.out.println("inter: " + inter);
報錯信息:
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)
原因分析:
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