目录
学习完三大框架,今天来学习一下如何将三个框架进行整合。三个框架中spring是负责整合的核心,所以整合三大框架主要还是看springmvc和mybatis如何与spring进行整合。
整合前首先简单创建一下项目
基础创建
取个名称创建web项目
注意一下location有没有错
补齐如下目录结构
导入所需要的jar包
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
1.Spring框架整合SpringMVC
spring框架的核心操作离不开ApplicationContext,也就是说如果每次通过spring获取对象时如果都需要创建ApplicationContext那么资源的多余消耗的比较大的,所以我们可以使用一个方法,让所有需要获取类的地方共享一个ApplicationContext。而ServletContext正好可以满足该任务,只需要创建好ApplicationContext后存放到ServletContext域中即可,那么什么时候创建ApplicationContext呢?
监听器
我们可以使用监听器监听,当ServletContext对象被创建时,也就是服务器开启时,那么就初始化ApplicationContext,并把他放在ServletContext域中共享。
自定义监听器
我们可以通过Servlet提供的监听器接口完成对ServletContext的监听
编写自己的监听器,实现ServletContextListener接口,重写初始化方法,在初始化方法中完成容器的创建。
public class ConfigListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
ServletContext servletContext = servletContextEvent.getServletContext();
//读取xml文件中的全局参数
String contextConfig = servletContext.getInitParameter("contextConfig");
System.out.println(contextConfig);
//根据web.xml配置文件中的全局参数找到配置文件的位置
ApplicationContext ac = new ClassPathXmlApplicationContext(contextConfig);
System.out.println(ac);
servletContext.setAttribute("context",ac);
System.out.println("Spring容器创建完成");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
定义完后在springmvc的web.xml中完成配置,这里的contextConfig对应了上文方法中的字符串参数,该参数用于寻找自己定义的spring配置文件。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--配置spring配置文件-->
<context-param>
<param-name>contextConfig</param-name>
<param-value>classpath:bean.xml</param-value>
</context-param>
<!--配置自定义监听器-->
<listener>
<listener-class>com.ling.web.listener.ConfigListener</listener-class>
</listener>
</web-app>
完成后当我们需要ApplicationContext时,可以直接通过ServletContext获取
使用ContextLoaderListener
spring自身为了这一问题提供了ContextLoaderListener类,该类是spring已经封装好的用于初始化ApplicationContext的监听器。我们在编写自定义监听器的时候发现,除了寻找spring配置文件时语句是动态的,其他情况都是静态的不变的,所以我们只需要在xml文件中配置好spring配置文件位置,然后配置ContextLoaderListener即可
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:bean.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
小结:如此就完成了spring与springmvc的整合,整合的核心就是如何将ApplicationContext与web项目建立联系,在整合中我们首先想到使用ServletContext存储ApplicationContext对象,以防上下文对象被重复创建,然后自定义监听器,在web项目启动时就完成ApplicationContext对象创建并且随时可以通过ServletContext获取。
2.Spring框架整合Mybatis
当我们还没有使用mybatis时,我们是在dao层实现类接口上直接用注解将实现类对象注册到容器中,但是我们学习了mybatis之后发现,dao层的实现类使用了代理模式实现,也就是说我们无法在不存在的实现类上写注解,这就成为了mybatis与spring整合的难题。
既然我们不能把代理对象放入容器,但是框架可以。导入spring-mybatis整合包之后框架拥有了这项能力,为此我们只需要在spring配置文件中配置好他所需要的条件即可。
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.ling">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 配置数据库连接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.DriverManagerDataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"/>
<property name="user" value="root"/>
<property name="password" value="239732"/>
</bean>
<!-- 配置SQLSessionFactory对象-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置scan扫描dao包-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ling.dao"></property>
</bean>
</beans>
配置主要有三个,首先我们倒推,如果我们需要获取代理对象,首先我们得有SQLSession,如果我们要有SqlSession,那么我们就得有SQLSessionFactory,所以我们配置了SqlSessionFactory,光有该对象不行,在SQLSessionFactoryBuilder使用build方法时,就已经解析了配置文件并把配置信息存放到environment环境中(这里可以看一下我的解读build源码那篇文章),而这里没有builder,那么环境数据就需要我们字节配置,于是就有了配置DataSource,此时我们只需要配置扫描包指定哪些包下的dao能添加进容器即可。
当配置完这三样我们发现,mybatis的主配置的主要内容都在这里了,那么此时的mybatis基本不需要了,后面我们直接基于注解开发即可。
案例:我们需要查询User
UserDao编写:
@Repository
public interface UserDao {
//查询所有用户
@Select("select * from user")
List<User> findAll();
}
UserService编写:
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public List<User> findAll() {
return userDao.findAll();
}
}
然后测试查询即可。
小结:spring框架与mybatis框架的整合主要是代理对象如何加入容器,为此spring底层封装了加入方法,我们只需要提供SqlSessionFactory对象,DataSource对象,以及扫描器对象即可。