tomcat啟動(dòng)時(shí)沒(méi)有把spring配置文件定義的bean加載進(jìn)來(lái)
最近在把自己的之前搭建的那個(gè)通用的ssh框架,配置成dubbo+zookeeper這樣的分布式架構(gòu)。搭建的思路就是把項(xiàng)目的service和controller分離出來(lái)。兩個(gè)項(xiàng)目之間的服務(wù)就通過(guò)zookeeper注冊(cè)和訂閱的方式來(lái)完成。service層的搭建還是比較順利的。在加入了zookeeper和dubbo的相關(guān)配置和分離了controller層的配置后接口服務(wù)能夠自動(dòng)的注冊(cè)到dubbo。

但是在搭建controller層的項(xiàng)目時(shí),在相關(guān)的配置完成后,服務(wù)通過(guò)tomcat啟動(dòng),一開(kāi)始是發(fā)現(xiàn)項(xiàng)目能夠訂閱到service層的服務(wù)的,以為就沒(méi)有錯(cuò)了,但是后面我在測(cè)試項(xiàng)目的整合的redis的時(shí)候發(fā)現(xiàn)controller層的容器沒(méi)有成功初始化redis配置文件中定義的bean對(duì)象。

(服務(wù)是已經(jīng)訂閱到的)
我在服務(wù)啟動(dòng)后把容器管理的bean對(duì)象信息都打印出來(lái)發(fā)現(xiàn)我spring整合redis配置文件定義的bean都沒(méi)有在里面。
[DUBBO] Refer dubbo service com.lung.application.inter.TestService from url zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?anyhost=true&application=dubbo-project-manager-consumer&check=false&default.delay=-1&default.retries=0&default.timeout=1200000&delay=-1&dubbo=2.5.3&interface=com.lung.application.inter.TestService&methods=queryAreaInfo,getResult&pid=29313&revision=1.0-SNAPSHOT&side=consumer×tamp=1539567979182, dubbo version: 2.5.3, current host: 172.17.0.1
[INFO ] 2018-10-15 09:46:19,274 method:com.lung.common.utils.ManagerBeansName.init(ManagerBeansName.java:25)
beanDefinitionCount29
roleController
testController
superController
managerBeansName
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0
mvcCorsConfigurations
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
mvcHandlerMappingIntrospector
mvcContentNegotiationManager
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.format.support.FormattingConversionServiceFactoryBean#0
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
mvcUriComponentsContributor
org.springframework.web.servlet.handler.MappedInterceptor#0
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0
fastJsonHttpMessageConverter
org.springframework.web.servlet.view.InternalResourceViewResolver#0
multipartResolver
[INFO ] 2018-10-15 09:46:19,541 method:org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:362)
Mapped URL path [/**] onto handler 'org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0'
[INFO ] 2018-10-15 09:46:19,628 method:org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.reg
這是我的springMVC配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--<context:property-placeholder ignore-unresolvable="true" location="classpath*:config.properties"/>-->
<!--1. 掃描 -->
<context:component-scan
base-package="com.lung.application,com.lung.common.controller,com.lung.common.utils">
<!--<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>-->
</context:component-scan>
<!--2.兩個(gè)標(biāo)準(zhǔn)配置 -->
<!--將springmvc不能處理的請(qǐng)求交給tomcat -->
<mvc:default-servlet-handler/>
<!--能支持springmvc更高級(jí)的一些功能,JSR303校驗(yàn),快捷的ajax...映射動(dòng)態(tài)請(qǐng)求 -->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<ref bean="fastJsonHttpMessageConverter"/>
<!--<ref bean="jsonMessageConverter"/>-->
</mvc:message-converters>
</mvc:annotation-driven>
<!--jackson配置json為空不輸出-->
<!--<bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<!–設(shè)置不輸出null字段–>
<property name="serializationInclusion" value="NON_NULL"/>
</bean>
</property>
</bean>-->
<!-- 使用fastJson來(lái)支持JSON數(shù)據(jù)格式 -->
<bean id="fastJsonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json</value>
</list>
</property>
<property name="features">
<list>
<!-- 避免循環(huán)引用 -->
<value>DisableCircularReferenceDetect</value>
<!-- 輸出key時(shí)是否使用雙引號(hào) -->
<value>QuoteFieldNames</value>
<!-- 數(shù)值字段如果為null,輸出為0,而非null -->
<value>WriteNullNumberAsZero</value>
<!-- List字段如果為null,輸出為[],而非null -->
<value>WriteNullListAsEmpty</value>
<!-- 字符類型字段如果為null,輸出為"",而非null -->
<value>WriteNullStringAsEmpty</value>
<!-- Boolean字段如果為null,輸出為false,而非null -->
<value>WriteNullBooleanAsFalse</value>
<!-- Date的日期轉(zhuǎn)換器 -->
<value>WriteDateUseDateFormat</value>
</list>
</property>
</bean>
<!--3.配置視圖解析器,方便頁(yè)面返回-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--file upload settings-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<property name="maxUploadSize" value="10485760000"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
<!--攔截器配置-->
</beans>
然后這是web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Project Web Application</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--1.Spring容器applicationContext.xml -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/spring-introduce.xml</param-value>
</context-param>
<!--2.springmvc的前端控制器 -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--3.編碼過(guò)濾 解決post亂碼 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--4、使用Rest風(fēng)格的URI,將頁(yè)面普通的post請(qǐng)求轉(zhuǎn)為指定的delete或者put請(qǐng)求 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
通過(guò)測(cè)試發(fā)現(xiàn)redis的bean對(duì)象沒(méi)有,報(bào)一個(gè)空指針異常。


在這里先給出解決方案:(其實(shí)這個(gè)算是我配置的問(wèn)題了,自己基礎(chǔ)不好包含而且粗心導(dǎo)致的。我的項(xiàng)目地址commonManageProject(mybatis-plus-version分支)
根本原因就是我在web.xml配置springDispatcherServlet的時(shí)候只是把springMVC的配置文件指定了,spring的配置文件沒(méi)有指定。所以導(dǎo)致了tomcat啟動(dòng)后,只加載了pringmvc配置文件指定的bean。(因?yàn)榉植际脚渲煤?,很多原?lái)定義在springMVC配置文件bean都定義在了spring配置文件中)
這個(gè)問(wèn)題在這里我卡住了很久都沒(méi)有解決,一開(kāi)始也是認(rèn)為是我自己的配置問(wèn)題,嘗試著從幾個(gè)方面找原因。
1、通過(guò)單元測(cè)試看看容器中redis對(duì)象是否存在:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:/spring/spring-introduce.xml",
"classpath*:/spring/springmvc.xml"})
public class TestRedis {
@Autowired
BaseRedisDao baseRedisDao;
@Test
public void TestRedis() {
try {
boolean set = baseRedisDao.set("baseRedisKey", "baseRedisvalue");
System.out.println(set);
} catch (Exception e) {
e.printStackTrace();
}
}
}
發(fā)現(xiàn)對(duì)象是存在的
[INFO ] 2018-10-15 10:03:57,861 method:com.alibaba.dubbo.config.ReferenceConfig.createProxy(ReferenceConfig.java:423)
[DUBBO] Refer dubbo service com.lung.application.inter.TestService from url zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?anyhost=true&application=dubbo-project-manager-consumer&check=false&default.delay=-1&default.retries=0&default.timeout=1200000&delay=-1&dubbo=2.5.3&interface=com.lung.application.inter.TestService&methods=queryAreaInfo,getResult&pid=30327&side=consumer×tamp=1539569037813, dubbo version: 2.5.3, current host: 172.17.0.1
[INFO ] 2018-10-15 10:03:57,868 method:com.lung.common.utils.ManagerBeansName.init(ManagerBeansName.java:25)
beanDefinitionCount39
poolConfig
jedisConnectionFactory
redisTemplate
baseRedisDao
com.lung.common.utils.PropertyPlaceholder#0
config
dubbo-project-manager-consumer
com.alibaba.dubbo.config.RegistryConfig
roleServiceImpl
testServiceImpl
roleController
testController
superController
managerBeansName
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0
mvcCorsConfigurations
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
mvcHandlerMappingIntrospector
mvcContentNegotiationManager
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.format.support.FormattingConversionServiceFactoryBean#0
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
mvcUriComponentsContributor
org.springframework.web.servlet.handler.MappedInterceptor#0
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0
fastJsonHttpMessageConverter
org.springframework.web.servlet.view.InternalResourceViewResolver#0
multipartResolver
[INFO ] 2018-10-15 10:03:58,045 method:org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:362)
Mapped URL path [/**] onto handler 'org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0'
2、通過(guò)ClassPathXmlApplicationContext查看spring容器是否把redis的相關(guān)對(duì)象給初始化了:
public class TestSpring {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext =
new ClassPathXmlApplicationContext("classpath:/spring/spring-introduce.xml");
int beanDefinitionCount = classPathXmlApplicationContext.getBeanDefinitionCount();
System.out.println(beanDefinitionCount);
String[] beanDefinitionNames = classPathXmlApplicationContext.getBeanDefinitionNames();
for (String str :
beanDefinitionNames) {
System.out.println(str);
}
}
}
發(fā)現(xiàn)也是正常的
[INFO ] 2018-10-15 10:06:13,113 method:org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:317)
Loading XML bean definitions from URL [file:/home/lung/IdeaProjects/commonManageProject/commons-manager/commons-manager-web/target/classes/dubbo/dubbo-consumer.xml]
[INFO ] 2018-10-15 10:06:13,214 method:
using logger: com.alibaba.dubbo.common.logger.log4j.Log4jLoggerAdapter
10
poolConfig
jedisConnectionFactory
redisTemplate
baseRedisDao
com.lung.common.utils.PropertyPlaceholder#0
config
dubbo-project-manager-consumer
com.alibaba.dubbo.config.RegistryConfig
roleServiceImpl
testServiceImpl
[INFO ] 2018-10-15 10:06:14,425 method:com.alibaba.dubbo.config.AbstractConfig$1.run(AbstractConfig.java:450)
無(wú)奈之下,我重新去復(fù)習(xí)一下springMVC的相關(guān)基礎(chǔ)了,后面發(fā)現(xiàn)自己好像在配置分布式服務(wù),把spring的配置做了更加細(xì)分的解耦后,我在web.xml配置servlet時(shí)只聲明的配置文件是不行的,這個(gè)時(shí)候需要把其他spring配置文件也指定才行。
所以:
<!--2.springmvc的前端控制器 -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring/springmvc.xml,classpath*:/spring/applicationContext-*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
修改成上面后測(cè)試接口就正常了:

謹(jǐn)記?。?!