- 首先简单理解Spring容器和SpringMVC的关系
- web.xml中spring的核心ContextLoaderListener初始化的上下文和springmvc的核心DispatcherServlet初始化的上下文关系:
- Spring容器和SpringMVC容器虽然是父容器与子容器的关系,但二者之间具有一定的独立性。具体来说,两个容器基于各自的配置文件分别进行初始化,只有在子容器找不到对应的Bean时,才回去父容器中去找并加载。
-
此外,一般地,SpringMVC容器只管理Controller,剩下的Service、Repository 和 Component 由Spring容器去管理,不建议两个容器上在管理Bean上发生交叉。
2. 环境搭建
工程目录如下:
然后就是部署Tomcat的web运行环境,注意web.xml,applicationContext.xml,spring-mvc.xml中关于路径的配置都是相对于classpath或WEB-INF配置的,因为实际生产环境中可能只有项目运行代码,并没有源文件,运行时需要到web项目下加载文件。
-
-
-
- web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 5 version="4.0"> 6 7 <welcome-file-list> 8 <welcome-file>index.jsp</welcome-file> 9 </welcome-file-list> 10 11 <!-- 用于加载Spring --> 12 <listener> 13 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 14 </listener> 15 <listener> 16 <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 17 </listener> 18 19 <!-- 配置applicationContext.xml文件位置 --> 20 <context-param> 21 <param-name>contextConfigLocation</param-name> 22 <param-value>classpath:config/spring/applicationContext.xml</param-value> 23 </context-param> 24 25 <!-- 加载log4j2 --> 26 <listener> 27 <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class> 28 </listener> 29 30 <!-- 配置log4j2.xml文件位置 --> 31 <context-param> 32 <param-name>log4jConfiguration</param-name> 33 <param-value>classpath:config/log/log4j2.xml</param-value> 34 </context-param> 35 36 <filter> 37 <filter-name>encodingFilter</filter-name> 38 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 39 <init-param> 40 <param-name>encoding</param-name> 41 <param-value>UTF-8</param-value> 42 </init-param> 43 <init-param> 44 <param-name>forceEncoding</param-name> 45 <param-value>true</param-value> 46 </init-param> 47 </filter> 48 <filter-mapping> 49 <filter-name>encodingFilter</filter-name> 50 <url-pattern>/*</url-pattern> 51 </filter-mapping> 52 53 <!-- 前端控制器配置 --> 54 <servlet> 55 <servlet-name>dispatcher</servlet-name> 56 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 57 <init-param> 58 <param-name>contextConfigLocation</param-name> 59 <param-value>classpath:config/spring/spring-mvc.xml</param-value> 60 </init-param> 61 <load-on-startup>1</load-on-startup> 62 </servlet> 63 <servlet-mapping> 64 <servlet-name>dispatcher</servlet-name> 65 <url-pattern>/</url-pattern> 66 </servlet-mapping> 67 68 <!-- 配置session过期时间(以分为单位) --> 69 <session-config> 70 <session-timeout>30</session-timeout> 71 </session-config> 72 </web-app>
- applicationContext.xml(applicationContext.xml文件内容如下,主要是配置dataSource (数据源)、事务管理、对dataSource 数据源进行事务管理、事务通知、事务 aop 配置等)
-
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 9 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 10 11 <description>Spring Configuration</description> 12 13 <context:component-scan base-package="cn.itcast.ssm.service"/> 14 <context:component-scan base-package="cn.itcast.ssm.mapper"/> 15 16 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"/> 17 18 <!-- dao层 --> 19 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 20 <!-- 注意在web环境下配置文件位置应设置为WEB-INF中相应的路径 --> 21 <property name="configLocation" value="classpath:config/mybatis/mybatis-config.xml"/> 22 <property name="dataSource" ref="dataSource"/> 23 </bean> 24 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 25 <property name="basePackage" value="cn.itcast.ssm.mapper"/> 26 <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> 27 </bean> 28 29 <!-- service层 --> 30 <bean id="itemsService" class="cn.itcast.ssm.service.impl.ItemsServiceImpl"/> 31 32 <!-- 事务配置 --> 33 <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 34 <property name="dataSource" ref="dataSource"/> 35 </bean> 36 <tx:advice id="txAdvice" transaction-manager="txManager"> 37 <tx:attributes> 38 <tx:method name="insert*" propagation="REQUIRED"/> 39 <tx:method name="save*" propagation="REQUIRED"/> 40 <tx:method name="delete*" propagation="REQUIRED"/> 41 <tx:method name="update*" propagation="REQUIRED"/> 42 <tx:method name="retrieve*" propagation="SUPPORTS" read-only="true"/> 43 <tx:method name="select*" propagation="SUPPORTS" read-only="true"/> 44 <tx:method name="find*" propagation="SUPPORTS" read-only="true"/> 45 </tx:attributes> 46 </tx:advice> 47 <aop:config> 48 <aop:pointcut id="pointcut1" expression="execution(* cn.itcast.ssm.service..*(..))"/> 49 <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/> 50 </aop:config> 51 </beans>
- spring-mvc.xml(主要是web层,如controller层和视图层的配置)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:mvc="http://www.springframework.org/schema/mvc" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <context:component-scan base-package="cn.itcast.ssm.controller"/> 11 12 <!-- 配置视图解析器 --> 13 <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 14 <property name="prefix" value="/WEB-INF/jsp/"/> 15 <property name="suffix" value=".jsp"/> 16 </bean> 17 </beans>
- web.xml
-
-
另外,在项目中配置log4j(log4j2)日志是很重要的,对于程序出错时查错,找错,调试有很大帮助,对于上面所提到的(注意web.xml,applicationContext.xml,spring-mvc.xml中关于路径的配置都是相对于classpath或WEB-INF配置的,因为实际生产环境中可能只有项目运行代码,并没有源文件,运行时需要到web项目下加载文件),如果配置的路径不是相对于classpath或者WEB-INF,没配置日志本人实现时抛出如下异常,由于信息量少,很难找出错误所在:
18-Jun-2019 09:26:36.836 信息 [Abandoned connection cleanup thread] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access: this web application instance has been stopped already. Could not load []. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access. java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load []. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access. at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1348) at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1007) at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.checkContextClassLoaders(AbandonedConnectionCleanupThread.java:96) at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:69) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834)
在加了log4j2日志后,显示:
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/config/mybatis/mybatis-config.xml] at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:141) at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:406) at org.mybatis.spring.SqlSessionFactoryBean.afterPropertiesSet(SqlSessionFactoryBean.java:380) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1692) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1630) ... 81 more
从而得知找不到相应配置文件,原因在于配置是相对于src的,而不是相对于classpath,修正后即可正常运行。
可见,项目中加入日志是很有帮助的。