1、依赖
<!-- jsp依赖 --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2.1-b03</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version>
2、配置web.xml配置文件
配置文件内容:
-
注册监听器ContextLoaderListener:创建spring容器并加载到servletContext中
-
配置中央调度器DispatcherServlet:将springmvc配置文件加载进来
-
注册字符集过滤器
-
配置DelegatingFilterProxy:配置springsecurity(目前不考虑)
(1) 注册监听器ContextLoaderListener
<!--注册spring的监听器--> <context-param> <param-name>contextConfigLocation</param-name> <!--spring配置文件的位置--> <param-value>classpath:conf/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
(2) 配置中央调度器DispatcherServlet
<!--注册中央调度器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--自定义springmvc读取的配置文件的位置--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:conf/dispatcherServlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>com.luca.controller.MyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/myservlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
(3) 注册字符集过滤器
<!--注册字符集过滤器--> <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> <!--强制请求对象(HttpServletRequest)使用encoding编码的值--> <init-param> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <!--强制应答对象(HttpServletResponse)使用encoding编码的值--> <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <!-- /*:表示强制所有的请求先通过过滤器处理。 --> <url-pattern>/*</url-pattern> </filter-mapping>
3、Spring整合MyBatis
(1) 依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency>
(2) 准备工作
-
定义实体类
-
定义Dao接口及其mapper映射文件
-
定义Service接口及其实现类
(3) 定义MyBatis配置文件
-
原来mybatis.xml配置文件内容:
-
配置数据源;
-
指定mapper.xml文件位置;
-
定义别名
-
日志级别
-
原来和现在对比
-
-
数据源配置不同:
-
在mapper.xml映射文件配置数据源。
-
spring配置文件中配置数据源,将数据源要交给Spring容器管理。
-
-
获取dao接口的不同:
-
-
通过SqlSession.getMapper(xxxDao.class)获取dao接口对象。
-
将dao接口对象添加到spring容器进行管理,使用@Repository或<bean>标签配置的方式,在spring配置文件中扫描进去。
-
-
-
现在spring整合mybatis后的mybatis.xml配置文件内容:只需要配置其他功能:mapper.xml映射文件、别名、日志级别等。
-
指定mapper.xml文件位置
-
定义别名
-
日志级别
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--settings:控制mybatis全局行为--> <settings> <!--设置mybatis输出日志--> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <!--设置别名--> <typeAliases> <!--name:实体类所在包名,类名就是别名--> <package name="com.luca.domain"/> </typeAliases> <!--sql mapper(sql映射文件)的位置)--> <mappers> <package name="com.luca.dao"/> </mappers> </configuration>
(4) 定义Spring配置文件
内容:
-
整合MyBatis,将dao对象加载到spring容器中
-
加载数据库属性文件
-
声明数据源
-
声明SqlSessionFactoryBean对象
-
声明mybatis扫描器,创建dao对象
-
配置组件扫描器,将service对象加载到spring容器中
-
数据源的配置:使用数据库属性文件
<!--加载jdbc.properties文件--> <context:property-placeholder location="jdbc.properties"/> <!--声明数据源DataSource,作用是连接数据库--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!--set注入给DruidDataSource提供连接数据库信息--> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxActive" value="${jdbc.maxActive}"/> </bean>
-
注册 SqlSessionFactoryBean
<!--声明mybatis提供的SqlSessionFactoryBean类,这个类内部创建SqlSessionaFactory对象--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--set注入,把数据库连接池付给了dataSource属性--> <property name="dataSource" ref="dataSource"/> <!--mybatis主配置文件的位置 configLocation属性是Resource类型,读取配置文件,其赋值使用value,指定文件的路径,使用classPath:表示文件的位置 mybatis.xml内配置了 别名、Mapper扫描器 --> <property name="configLocation" value="classpath:mybatis.xml"/> </bean>
-
定义 Mapper 扫描配置器 MapperScannerConfigurer
<!--注册Mapper扫描配置器: 原来创建dao对象,使用SqlSession的getMapper(StudentDao.class) 现在使用MapperScannerConfigurer:在内部调用getMapper()生成每个dao接口的代理对象 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--指定SqlSessionFactory对象的id--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!--指定包名,包名是dao接口所在的包名 MapperScannerConfigurer会扫描这个包中的所有接口,把每个接口都执行一次getMapper()方法,得到每个接口的dao对象。把创建好的dao对象放入到spring的容器中。 相当于实现了,SqlSession.getMapper(xxxDao.class)方法 --> <property name="basePackage" value="com.luca.dao"/> </bean>
(5) Spring整合MyBatis配置文件的全部配置
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--加载jdbc.properties文件--> <context:property-placeholder location="jdbc.properties"/> <!--加载组件扫描器,包com.luca.service中带有@Component,@Repository,@Service,@Controller注解的类对象加载到spring容器中--> <context:component-scan base-package="com.luca.service"/> <!--声明数据源DataSource,作用是连接数据库--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!--set注入给DruidDataSource提供连接数据库信息--> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxActive" value="${jdbc.maxActive}"/> </bean> <!--声明mybatis提供的SqlSessionFactoryBean类,这个类内部创建SqlSessionaFactory对象--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--set注入,把数据库连接池付给了dataSource属性--> <property name="dataSource" ref="dataSource"/> <!--mybatis主配置文件的位置 configLocation属性是Resource类型,读取配置文件,其赋值使用value,指定文件的路径,使用classPath:表示文件的位置 mybatis.xml内配置了 别名、Mapper扫描器 --> <property name="configLocation" value="classpath:mybatis.xml"/> </bean> <!--注册Mapper扫描配置器: 原来创建dao对象,使用SqlSession的getMapper(StudentDao.class) 现在使用MapperScannerConfigurer:在内部调用getMapper()生成每个dao接口的代理对象 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--指定SqlSessionFactory对象的id--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!--指定包名,包名是dao接口所在的包名 MapperScannerConfigurer会扫描这个包中的所有接口,把每个接口都执行一次getMapper()方法,得到每个接口的dao对象。把创建好的dao对象放入到spring的容器中。 相当于实现了,SqlSession.getMapper(xxxDao.class)方法 --> <property name="basePackage" value="com.luca.dao"/> </bean> </beans>
(6) Spring配置文件总结
-
<bean>:声明对象
-
<context:component-scan>:组件扫描器
-
整合mybatis
-
<context:property-placeholder>:加载数据库属性文件
-
<bean class="com.alibaba.druid.pool.DruidDataSource"/>:声明数据源
-
<bean class="org.mybatis.spring.SqlSessionFactoryBean">:声明SqlSessionFactoryBean对象
-
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">:声明mybatis扫描器,创建dao对象
-
AOP实现
-
<bean class="com.luca.service.MyAspectj"/>:声明切面对象
-
<aop:aspectj-autoproxy/>:aspectj自动代理生成器
-
spring事务管理
-
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">:声明事务管理器
-
<tx:annotation-driven>:开启事务注解驱动
-
aspectj事务管理
-
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">:声明事务管理器
-
<tx:advice>:配置事务通知
-
<aop:config>:配置增强器
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--创建对象--> <bean id="someService" class="com.luca.service.SomeServiceImpl"/> <!--开启组件扫描--> <context:component-scan base-package="com.luca"/> <!--整合MyBatis--> <!--加载外部属性文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--声明数据源DataSource,作用是连接数据库--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!--set注入给DruidDataSource提供连接数据库信息--> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxActive" value="${jdbc.maxActive}"/> </bean> <!--声明mybatis提供的SqlSessionFactoryBean类,这个类内部创建SqlSessionaFactory对象--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--set注入,把数据库连接池付给了dataSource属性--> <property name="dataSource" ref="dataSource"/> <!--mybatis主配置文件的位置--> <property name="configLocation" value="classpath:mybatis.xml"/> </bean> <!--注册Mapper扫描配置器--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--指定SqlSessionFactory对象的id--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!--指定包名,包名是dao接口所在的包名--> <property name="basePackage" value="com.luca.dao"/> </bean> <!--Aspectj实现AOP--> <!--声明切面对象--> <bean id="myAspect" class="com.luca.service.MyAspectj"/> <!--声明自动代理生成器:使用aspectj框架内部的功能,创建目标对象的代理对象--> <aop:aspectj-autoproxy/> <!--Spring事务--> <!--1.声明事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--连接数据库--> <property name="dataSource" ref="dataSource"/> </bean> <!--2.开启事务注解驱动,让spring使用注解管理驱动,创建代理对象--> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> <!--Aspectj事务管理--> <!--声明式事务处理:和源代码完全分离--> <!--1.声明事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--2.声明业务方法的事务属性(隔离级别,传播行为,超出时间) id:自定义名称,表示<tx:advice>和</tx:advice>之间的配置内容 --> <tx:advice id="myAdvice" transaction-manager="transactionManager"> <!-- tx:attributes:配置事务属性 --> <tx:attributes> <!--tx:method:给具体的方法配置事务属性,method可以有多个,分别给不同的方法设置事务 name:方法名称,1)完整的方法名称,不带有包和类 2)方法可以使用通配符,*表示任意字符 --> <tx:method name="buy" propagation="REQUIRED" isolation="DEFAULT"/> <!--使用通配符,指定很多的方法--> <!--建立统一命名规范,指定添加方法--> <tx:method name="add*"/> <!--指定修改方法--> <tx:method name="modify*"/> <!--删除方法--> <tx:method name="remove*"/> <!--查询方法,query,search,find--> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <!--3.配置AOP--> <aop:config> <!--配置切入点表达式:指定哪些包中的类要使用事务 id:切入点表达式的名称,唯一值 expression:切入点表达式,指定哪些类要使用事务,aspectj会创建代理事务 --> <aop:pointcut id="servicePt" expression="execution(* *..service..*.*(..))"/> <!--配置增强器:关联advice和pointcut advice-ref:通知,上面 tx:advice 的相关配置信息 pointcut-ref:切入点表达式的id --> <aop:advisor advice-ref="myAdvice" pointcut-ref="servicePt"/> </aop:config> </beans>
4、Spring整合SpringMVC
(1) 准备工作
-
定义处理器Controller方法
@Controller @RequestMapping("/student") public class StudentController { @Autowired private StudentService service; @RequestMapping("/addStudent.do") public ModelAndView registStudent(Student student) { //调用service业务方法 } }
-
编写jsp页面文件
(2) 定义SpringMVC配置文件
内容:
-
组件扫描器,扫描Controller所在的包,将controller对象加载到spring容器中
-
视图解析器
-
注册注解驱动
-
异常处理机制
-
配置转发映射
-
配置拦截器
-
组件扫描器
<!--配置自动扫描的包--> <context:component-scan base-package="com.atguigu.crowd.mvc"/>
-
视图解析器
<!--配置视图解析器--> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/"/> <property name="suffix" value=".jsp"/> </bean>
-
注册注解驱动
<!--配置SpringMVC注解驱动--> <mvc:annotation-driven/>
-
配置基于XML的异常映射
在项目中基于XML的异常映射和基于注解的异常映射都得有,基于注解的针对于Controller方法抛出的异常,其他的是基于XML的处理
<!--配置基于XML的异常映射--> <bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!--配置异常的类型和具体视图页面的对应关系--> <property name="exceptionMappings"> <props> <!--key属性指定异常全类名,标签体中写对应的视图名(这个值要拼前后缀得到具体路径)--> <prop key="java.lang.Exception">system-error</prop> <prop key="com.atguigu.crowd.exception.AccessForbiddenException">admin-login</prop> </props> </property> </bean>
-
配置转发映射
<mvc:view-controller path="/admin/to/login/page.html" view-name="admin-login"/> <mvc:view-controller path="/admin/to/main/page.html" view-name="admin-main"/> <mvc:view-controller path="/admin/to/addAdmin/page.html" view-name="admin-add"/> <mvc:view-controller path="/role/to/page.html" view-name="role-page"/> <mvc:view-controller path="/menu/to/page.html" view-name="menu-page"/>
-
配置拦截器
<mvc:interceptors> <mvc:interceptor> <!--mvc:mapping配置要拦截的资源--> <!-- /* 对应一层路径,比如:/aaa --> <!-- /** 对应多层路径,比如:/aaa/bbb 或 /aaa/bbb/ccc --> <mvc:mapping path="/**"/> <!-- mvc:exclude-mapping 配置不拦截的资源 --> <mvc:exclude-mapping path="/admin/to/login/page.html"/> <mvc:exclude-mapping path="/admin/do/login.html"/> <mvc:exclude-mapping path="/admin/do.logout.html"/> <bean class="com.atguigu.crowd.mvc.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors>
(3) SpringMVC配置文件总结
-
组件扫描器:<context:component-scan base-package>
-
视图解析器:<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
-
声明注解驱动:<mvc:annotation-driven />
-
转发映射:<mvc:view-controller />
-
静态资源访问:
-
<mvc:default-servlet-handler/>:创建DefaultServletHttpRequestHandler处理器对象
-
<mvc:resources/>:加入静态资源
-
<mvc:annotation-driven />声明注解驱动
-
异常处理机制:
-
xml方式:<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
-
注解方式:
-
组件扫描器扫描@ControllerAdvice注解所在的包
-
声明注解驱动
-
注册拦截器:<mvc:interceptors>
<?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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--声明组件扫描器--> <context:component-scan base-package="com.luca.security.config.controller"/> <!--声明 springmvc框架中的视图解析器,帮助开发人员设置视图文件的路径--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀:视图文件的路径--> <property name="prefix" value="/WEB-INF/view/"/> <!--后缀:视图文件的扩展名--> <property name="suffix" value=".jsp"/> </bean> <!--声明注解驱动--> <mvc:annotation-driven/> <!--静态资源访问--> <!--方式一--> <mvc:default-servlet-handler/> <!--方式二:使用一个配置语句,指定多种静态资源的访问--> <mvc:resources mapping="/static/**" location="/static/"/> <!--异常处理--> <!--配置基于xml的异常映射--> <bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="java.lang.Exception">system-error</prop> </props> </property> </bean> <!--基于注解的异常映射--> <context:component-scan base-package="com.luca.controller"/> <!--注册拦截器--> <mvc:interceptors> <mvc:interceptor> <!--mvc:mapping配置要拦截的资源--> <!-- /* 对应一层路径,比如:/aaa --> <!-- /** 对应多层路径,比如:/aaa/bbb 或 /aaa/bbb/ccc --> <mvc:mapping path="/**"/> <!-- mvc:exclude-mapping 配置不拦截的资源 --> <mvc:exclude-mapping path="/admin/to/login/page.html"/> <mvc:exclude-mapping path="/admin/do/login.html"/> <mvc:exclude-mapping path="/admin/do.logout.html"/> <bean class="com.atguigu.crowd.mvc.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors> </beans>
5、问题
(1) spring整合mybatis时,dao接口实际并未使用@repository这个注解,因为在spring.xml配置文件中,使用MapperScannerConfigurer扫描dao接口将其加入到了spring容器中。
<!--创建dao对象,使用SqlSession的getMapper(StudentDao.class)
MapperScannerConfigurer:在内部调用getMapper()生成每个dao接口的代理对象
注册Mapper扫描配置器
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--指定SqlSessionFactory对象的id-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--指定包名,包名是dao接口所在的包名
MapperScannerConfigurer会扫描这个包中的所有接口,把每个接口都执行一次getMapper()方法,
得到每个接口的dao对象。把创建好的dao对象放入到spring的容器中。
-->
<property name="basePackage" value="com.luca.dao"/>
</bean>
(2) SpringWeb,使用监听器 ContextLoaderListener,将spring容器注册进servletContext里面
使用@Autowared注解的时候,怎么获取到spring容器的
不是springweb的时候,没有加到servletContext里,怎么获取spring容器的
流程:
首先将对象放进spring容器里:1)使用@Component等注解,在spring配置文件扫描;2)在spring配置文件使用<bean>标签注册
怎么获得spring容器里的对象:1)使用new ClassPathXmlApplicationContext("applicationContext.xml")获取容器,使用.getBean()来获取对象
2)使用@Autowired注解,就不需要获取容器了?猜想:会自动得到spring容器,然后在容器里找到对象