首先需要讲的是web.xml的配置。而讲web.xml配置前,先了解一下tomcat启动时都做了些什么事情。
1.tomcat启动后,会自动创建一个servletContext上下文环境,该上下文是可共享的。
2.然后加载web.xml文件,读取里面的listener和context-param。通过ContextLoaderListener(可直接声明此类,也可在代码中重写该类,实现自己特有的方法)初始化webApplicationContext作为父上下文,context-param以键值对的形式存在在servletContext中。换一句话说,contextLoaderListener会自动装配ApplicationContext的配置信息,所有的bean都是从这里创建出来的。所以我们获取bean的方式可以写成ContextLoaderListener.getCurrentWebApplicationContext("studentService"),也说明子上下文可是使用父上下文的方法。
3.加载子上下文,读取web.xml中配置的servlet,初始化为servletContext上下文,将webApplicationContext设置为他的父容器
配置的代码如下,详细说明见https://www.cnblogs.com/wkrbky/p/5929943.html
<?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"
id="WebApp_ID" version="3.0">
<display-name>ssh</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 配置spring ioc容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/spring-context.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置springmvc 的DispatcherServlet -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<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>
</web-app>
web.xml配置好后,接下来配置spring-context.xml,即父容器的配置
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd"
default-lazy-init="true">
<!--启动spring的一些注解,主要包括:向 Spring 容器注册如下4 个BeanPostProcessor,有配置component-scan就不需要再配置annotation-config-->
<!--<context:annotation-config/>-->
<!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。 -->
<context:component-scan base-package="com.yeki">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
然后是spring-mvc.xml配置
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<description>Spring MVC Configuration</description>
<!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。 -->
<context:component-scan base-package="com.yeki">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- REST中根据URL后缀自动判定Content-Type及相应的View -->
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="mediaTypes" >
<map>
<entry key="xml" value="application/xml"/>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="ignoreAcceptHeader" value="true"/>
<property name="favorPathExtension" value="true"/>
</bean>
<!-- 默认的注解映射的支持,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping -->
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters>
<!-- 将StringHttpMessageConverter的默认编码设为UTF-8 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" />
</bean>
<!-- 将Jackson2HttpMessageConverter的默认格式化输出为false -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list><value>application/json;charset=UTF-8</value></list>
</property>
<property name="prettyPrint" value="false"/>
<property name="objectMapper">
<bean class="com.yeki.core.mapper.JsonMapper" />
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/webpage/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1" />
</bean>
</beans>
配置文件配置好都新增一个controller
package com.yeki.test.controller;
import com.yeki.test.entity.Student;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping(value = "test")
public class PageController {
@ResponseBody
@RequestMapping(value="get")
public Student getStudent(){
Student s=new Student();
s.setAge(10);
s.setName("haha");
return s;
}
}
启动服务器,访问如下
对了,pom文件见附件地址https://download.csdn.net/download/u010924720/11456887,可能会多了很多除了springmvc以外的其他jar包,看着删掉就行了
接下来就需要与mybatis整合了,这时候需要在spring-context.xml中配置mybatis需要的一些东东。
(1)首先需要将数据库中连接信息放入一个配置文件中,这里我的sql配置取名为mes.properties.,然后加载配置文件,下面也给出了注释。
(2)加载到配置文件后就需要配置dataSource数据源了,创建了一个bean,id就叫dataSource,基础信息配置好后就需要加载了。
(3)扫描项目中所有的Mapper接口:创建一个mapperScannerConfigurer的Bean,里面需要的属性为
basePackage(mapper接口所有在路径)
annotationClass(该属性起到一个过滤作用,如果设置了该属性,那myBatis的接口只能包含该注解,才会被扫描进去)
sqlSessionFactoryBeanName(存在多个数据源才需要配置)
(4)配置sqlSessionFactory,包含属性
dataSource:数据源
typeAliasesPackage:该属性可以给包中的类注册别名,注册后可以直接使用类名,不需要使用完整的包加类名
typeAliasesSuperType:限制只扫描集成了某个父类的类
mapperLocations:指定sql.xml的路径
configLocation:指定mybatis的一些其他配置
修改后的spring-context.xml如下
<?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:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd" default-lazy-init="true"> <!-- 加载配置属性文件 --> <context:property-placeholder ignore-unresolvable="true" location="classpath:/properties/mes.properties" /> <!-- 加载应用属性实例,可通过 @Value("#{APP_PROP['jdbc.driver']}") String jdbcDriver 方式引用 --> <util:properties id="APP_PROP" location="classpath:/properties/mes.properties" local-override="true"/> <!--启动spring的一些注解,主要包括:向 Spring 容器注册如下4 个BeanPostProcessor,有配置component-scan就不需要再配置annotation-config--> <!--<context:annotation-config/>--> <!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。 --> <context:component-scan base-package="com.yeki"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- MyBatis begin --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--扫描moudles下面的所有类--> <property name="typeAliasesPackage" value="com.yeki.modules"/> <!--限制只扫描继承了BaseEntity的类--> <property name="typeAliasesSuperType" value="com.yeki.core.mapper.BaseEntity"/> <!--指定sql.xml的路径--> <property name="mapperLocations" value="classpath*:com/**/modules/**/*Mapper.xml"/> <property name="configLocation" value="classpath:/mybatis/mybatis-config.xml" /> <property name="configurationProperties"> <props> <prop key="dual">${jdbc.dual}</prop> </props> </property> </bean> <!-- 扫描basePackage下所有以@MyBatisMapper注解的接口 --> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--这个属性一般都用不到,只有当你配置多数据源的时候,这是会有多个sqlSessionFactory,你就需要通过该属性来指定哪一个sqlSessionFactory(值为SqlSessionFactoryBean <bean>配置中的id属性)。--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> <property name="basePackage" value="com.yeki.modules"/> <!--该属性实际上就是起到一个过滤的作用,如果设置了该属性,那么MyBatis的接口只有包含该注解,才会被扫描进去。--> <property name="annotationClass" value="com.yeki.core.persistence.annotation.MyBatisMapper"/> </bean> <!-- 定义事务 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 配置 Annotation 驱动,扫描@Transactional注解的类定义事务 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> <!-- MyBatis end --> <!-- 数据源配置, 使用 BoneCP 数据库连接池 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass --> <property name="driverClassName" value="${jdbc.driver}" /> <!-- 基本属性 url、user、password --> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="${jdbc.pool.init}" /> <property name="minIdle" value="${jdbc.pool.minIdle}" /> <property name="maxActive" value="${jdbc.pool.maxActive}" /> <!-- 配置获取连接等待超时的时间 --> <property name="maxWait" value="60000" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="300000" /> <property name="validationQuery" value="${jdbc.testSql}" /> <property name="testWhileIdle" value="true" /> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用) <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> --> <!-- 配置监控统计拦截的filters --> <property name="filters" value="stat" /> </bean> </beans>
MyBatisMapper文件如下
package com.yeki.core.persistence.annotation; import org.springframework.stereotype.Component; import java.lang.annotation.*; /** * 标识MyBatis的DAO,方便{@link org.mybatis.spring.mapper.MapperScannerConfigurer}的扫描。 * @author yeki * @version 2019-7-28 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Component public @interface MyBatisMapper { /** * The value may indicate a suggestion for a logical component name, * to be turned into a Spring bean in case of an autodetected component. * @return the suggested component name, if any */ String value() default ""; }
此时只需要在mapper接口中声明一下@MyBatisMapper即可
package com.yeki.modules.user.mapper; import com.yeki.core.persistence.annotation.MyBatisMapper; import com.yeki.modules.user.entity.UserEntity; import java.util.List; @MyBatisMapper public interface UserMapper { List<UserEntity> getList(); }