Spring+SpringMVC+Mybatis知识点复习【SSM框架复习笔记】

导读:本篇文章讲解 Spring+SpringMVC+Mybatis知识点复习【SSM框架复习笔记】,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、Spring部分

1. Spring 的含义:

Spring 在不同的场景中表示不同的含义。早期的时候它被用来指代Spring Framework项目本身,这也是它一开始的含义。随着时间的推移,在Spring Framework之上建立了其他Spring项目,比如SpringSecurity、SpringBoot、SpringCloud。大部分情况下,当人们聊到Spring时,他们所说的 Spring 是 Spring 整个家族。

Spring 是一个轻量级的开源框架,是为解决企业应用开发的复杂性而创建的。而在我的理解中,Spring 的主要就解决了两件事情(当然它还解决了数据访问、远程调用、单元测试等问题),分别对应 Spring 的两个设计思想 IOC 和 AOP:

  • IOC 容器(解耦合):解决各种 new 对象的问题
  • AOP (切面编程):把非业务范畴的功能,提取成一个切面,统一实现

2. 核心特性(Core)

  • IoC 容器(IoC Container)
  • Spring 事件(Events)
  • 资源管理(Resources)
  • 国际化(i18n)
  • 校验(Validation)
  • 数据绑定(Data Binding)
  • 类型转换(Type Conversion)
  • Spring 表达式(Spring Express Language)
  • 面向切面编程(AOP)

这里我们就可以解释BeanFactory和ApplicationContext的区别了

public interface BeanFactory {
	// 根据bean名字查找
	Object getBean(String name) throws BeansException;
	// Bean延迟查找
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
	// 判断容器中有没有这个名字的bean
	boolean containsBean(String name);
	// 判断一个Bean是不是单例
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
    
    ...

}

BeanFactory 看下去可以去做IOC当中的大部分事情,为什么还要去定义一个ApplicationContext 呢?
我们可以看一下ApplicationContext 的 结构图
在这里插入图片描述

从图中可以看到 ApplicationContext 它由BeanFactory接口派生而来,因而提供了BeanFactory所有的功能。除此之外context包还提供了以下的功能:

  1. MessageSource, 提供国际化的消息访问
  2. 资源访问,如URL和文件
  3. 事件传播,实现了ApplicationListener接口的bean
  4. 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层

3. IOC

3.1 什么是IOC?

IoC 全称为 Inversion of Control,翻译为 “控制反转”,说白了,IOC 就是由 Spring IOC 容器来负责对象的生命周期和对象之间的关系。

所谓控制:就是对象的创建、初始化、销毁。

  • 创建对象:原来是 new 一个,现在是由 Spring 容器创建。
  • 初始化对象:原来是对象自己通过构造器或者 setter 方法给依赖的对象赋值,现在是由 Spring 容器自动注入。
  • 销毁对象:原来是直接给对象赋值 null 或做一些销毁操作,现在是 Spring 容器管理生命周期负责销毁对象。

所谓反转

其实是反转的控制权,前面提到是由 Spring 来控制对象的生命周期,那么对象的控制就完全脱离了我们的控制,控制权交给了 Spring 。这个反转是指:我们由对象的控制者变成了 IOC 的被动控制者。

总结:IOC 解决了繁琐的对象生命周期的操作,解耦了我们的代码。

3.2 IOC 能做什么?

IOC 容器完美解决了耦合问题,甚至可以让互不相关的对象产生注入关系。

在 IOC 模式下,你只需要设计良好的流程和依赖,定义出需要什么,然后把控制权交给 Spring 即可。

3.3 IOC、DI、DL的区别

DI和DL:即依赖注入和依赖查找。

我们常说IOC和DI,却忽略了DL,其实后两者都是IOC的具体实现,在Spring中主要运用到的是DI,但并不代表没有DL(依赖查找)。例如我们刚学Spring时写的测试程序。

依赖注入主要分为 手动模式 和 自动模式

  • 手动模式:XML 资源配置元信息,Java 注解配置元信息,API 配置元信息
    在这里插入图片描述
    在这里插入图片描述
    自动装配的局限性和缺点:
  • 通过 propertyconstructor-arg 进行依赖设定,这种显式的设定始终会覆盖自动装配。你不能自动装配简单的属性,例如基本类型,Strings ,和 Classes (以及这些简单属性的数组)。这种限制是由设计造成的。
  • 自动装配不如显示装配精确。如前表所述,尽量小心让Spring避免去猜测模棱两可的事情(知秋注:比如两个相同类型的bean,也没有其他特殊指定,Spring不知道该选择哪个来进行注入操作),以免产生意想不到的结果。如果你不仔细,你的Spring所管理对象之间的关系不再明确。
  • 装配信息可能对从Spring容器中生成文档的工具不可用。
  • 容器内的多个bean definition可能与要自动装配的setter方法或构造函数参数指明的类型匹配。对于数组,集合,或者 Map 实例,这就不是什么问题了。然而,对于期望单值的依赖项来说,这种歧义性不能随意的解决。如果没有唯一的bean可用,将抛出一个异常。

总结:IOC 是一种设计思想。从 IOC 到 DI 和 DL ,就是从理论到实践。程序把依赖交给容器,容器帮你管理依赖,这就是依赖注入的核心。依赖注入降低了开发的成本,提高了代码复用率、软件的灵活性

4. Spring常见注解:

@Autowired

自动导入对象到类中,被注入进的类同样要被 Spring 容器管理比如:Service 类注入到 Controller 类中。

@Autowired和@Inject、@Resource,可以与@Qualifier或者@Name配合使用,防止多实例注入时出错,以及值注入@Value。

注解 解析 用法
@Autowired 通过AutowiredAnnotationBeanPostProcessor类实现的依赖注入,默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常。 可注释在字段上,在方法上
@Inject 作用与@Autowired一样 可注释在字段上,在方法上、构造器上
@Resource 默认按照名称进行装配,名称可以通过name属性进行指定 可注释在字段上,在方法上
@Qualifier 限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者,可与@Autowired或者@Inject进行组合使用,进行精确注入 可注释字段上,在方法上、参数上以及注解中

@Scope作用域和生命周期

@Scope 声明 Spring Bean 的作用域 ,四种常见的 Spring Bean 的作用域:

  • singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
  • prototype : 每次请求都会创建一个新的 bean 实例。
  • request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
  • session : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。

具有4个作用域,以及生命周期过程处理@PostConstruct、@PreDestroy 。

注解 解析 用法
@Scope 具有4个作用域singleton,prototype,session,request,默认为singleton单例模式 可注释在Class创建时
@PostConstruct 相当于init-method,使用在方法上,当Bean初始化时执行 可注释在方法上
@PreDestroy 相当于destory-method,使用在方法上,当Bean销毁时执行 可注释在方法上

案例:

@Service //组件注入,注明为service组件
@Scope("prototype")//声明Scope为Prototype
public class UseFunctionService {
    
    @Autowired //默认按type注入
    @Qualifier("functionService") //精确注入
    FunctionService functionService;
    
    @Resource(name="baseDao")//默认按name注入,可以通过name和type属性进行选择性注入
    private BaseDao baseDao;
    
    @Inject
    @Qualifier("userServiceImpl") //精确注入  
    public IUserService userService;  
    
    @PostConstruct//执行完构造函数后执行
    public postConstruct(){
        System.out.println("postConstruct");
    }
    
    @PreDestroy//在销毁Bean前执行
    public perDestroy(){
         System.out.println("perDestroy");
    }
    
    @Autowired   
    public void setUserDao(@Qualifier("userDao") UserDao userDao) {   
     this.userDao = userDao;   
    }  

    public String SayHello(String word){
        return functionService.sayHello(word);
    }
}

@Component,@Repository,@Service, @Controller

@component,而其余 @Controller@Service@Repository都组合了@component注解,主要为便于使用者Class组件进行归类。默认加载IOC容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作

注解 解析 用法
@Component 组件注解,使用了该注解会基于注释的配置和类路径扫描时,会自动扫描并加载Class到ICO容器中 注释在类上
@Controller 应用在MVC层(控制层)DispatcherServlet会自动扫描注解了此注解的类,然后将web请求映射到注解了@RequestMapping的方法上 注释在类上
@Service 对应服务层,主要涉及一些复杂的逻辑,应用在service层(业务逻辑层) 注释在类上
@Repository 对应持久层即 Dao 层,主要用于数据库相关操作,应用在dao层(数据访问层) 注释在类上

@Configuration

一般用来声明配置类,可以使用 @Component注解替代,不过使用Configuration注解声明配置类更加语义化。 主要区别在于Configuration在Spring加载的时候,会被CGLib代理,里面的@Bean不会出现重复实例化

官方有说到 ->

@Bean methods are to be declared within @Configuration classes, ensuring that “full” mode is always used and that cross-method references therefore get redirected to the container’s lifecycle management. This prevents the same @Bean method from accidentally being invoked through a regular Java call, which helps to reduce subtle bugs that can be hard to track down when operating in “lite” mode.

机器翻译:在常见的场景中,@Bean方法将在@Configuration类中声明,以确保始终使用“full”模式,并因此将交叉方法引用重定向到容器的生命周期管理。这可以防止通过常规Java调用意外调用相同的@Bean方法,这有助于减少在“lite”模式下操作时难以跟踪的细微bug。

注:读取配置信息@Value,事务注解@Transactional等,还有很多注解就不一一赘述了

二、SpringMVC部分

1. SpringMVC的含义

  • 概念:SpringMVC是Spring框架中的一个分支,是基于Java实现MVC的轻量级Web框架
  • 核心:Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计的。

总结: SpringMVC 本质上还是在使用Servlet处理,并在其基础上进行了封装简化了开发流程,提高易用性、并使用程序逻辑结构变得更清晰

2. SpringMVC的执行流程

在这里插入图片描述
在这里插入图片描述

3. SpringMVC常见注解

@RequestMapping 处理常见的 HTTP 请求类型

5 种常见的请求类型:

  • GET :请求从服务器获取特定资源。举个例子:GET /users(获取所有用户)
  • POST :在服务器上创建一个新的资源。举个例子:POST /users(创建用户)
  • PUT :更新服务器上的资源(客户端提供更新后的整个资源)。举个例子:PUT /users/12(更新编号为 12 的用户)
  • DELETE :从服务器删除特定的资源。举个例子:DELETE /users/12(删除编号为 12 的用户)
  • PATCH :更新服务器上的资源(客户端提供更改的属性,可以看做作是部分更新),使用的比较少。
注解 解析
@GetMapping @GetMapping("users") 等价于@RequestMapping(value="/users",method=RequestMethod.GET)
@PostMapping @PostMapping("users") 等价于@RequestMapping(value="/users",method=RequestMethod.POST)
@PutMapping @PutMapping("/users/{userId}") 等价于@RequestMapping(value="/users/{userId}",method=RequestMethod.PUT)
@DeleteMapping @DeleteMapping("/users/{userId}")等价于@RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE)

前后端传值@PathVariable@RequestParam

@PathVariable用于获取路径参数,@RequestParam用于获取查询参数。

举个简单的例子:

@GetMapping("/users/{userId}/teachers")
public List<Teacher> getKlassRelatedTeachers(
					@PathVariable("userId") Long userId,
    				@RequestParam(value = "type", required = false) String type){
    ...
}

如果我们请求的 url 是:/users/{123456}/teachers?type=web

那么我们服务获取到的数据就是:userIDd=123456,type=web

@RequestBody

用于读取 Request 请求(可能是 POST,PUT,DELETE,GET 请求)的 body 部分并且Content-Type 为 application/json 格式的数据,接收到数据之后会自动将数据绑定到 Java 对象上去。系统会使用HttpMessageConverter或者自定义的HttpMessageConverter将请求的 body 中的 json 字符串转换为 java 对象。

@RestController

@ResponseBody 注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据,常见于前后端分离项目。

@RestController注解是@Controller和@ResponseBody的合集,表示这是个控制器 bean,并且是将函数的返回值直 接填入 HTTP 响应体中,是 REST 风格的控制器。

JSR303 一套JavaBean参数校验的标准

它定义了很多常用的校验注解 一些常用的字段验证的注解

  • @NotEmpty 被注释的字符串的不能为 null 也不能为空
  • @NotBlank 被注释的字符串非 null,并且必须包含一个非空白字符
  • @Null 被注释的元素必须为 null
  • @NotNull 被注释的元素必须不为 null
  • @AssertTrue 被注释的元素必须为 true
  • @AssertFalse 被注释的元素必须为 false
  • @Pattern(regex=,flag=)被注释的元素必须符合指定的正则表达式
  • @Email 被注释的元素必须是 Email 格式。
  • @Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @DecimalMin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @Size(max=, min=)被注释的元素的大小必须在指定的范围内

三、mybatis部分

1. mybatis的含义

MyBatis 的前身是 iBatis,iBatis是 Apache 软件基金会下的一个开源项目。2010 年该项目从Apache 基金会迁出,并改名为MyBatis。同期,iBatis停止维护。 MyBatis是一种半自动化的Java持久层框架,其通过注解或XML 的方式将对象和SQL 关联起来。之所以说它是半自动的,是因为和Hibernate 等一些可自动生成SQL的ORM框架相比,使用MyBatis需要用户自行维护SQL,维护SQL 的工作比较繁琐,但也有好处。比如我们可控制SQL逻辑,可对其进行优化,以提高效率。

2. mybatis的核心部分

2.1 MyBatis配置XML文件的层次结构

<?xml version="1. 0" encoding="UTF-8"?>
<configuration> <!--配置 -->
    <properties/> <!--属性-->
    <settings/> <!--设置-->
    <typeAliases/> <!--类型命名-->
    <typeHandlers/> <!--类型处理器-->
    <objectFactory/> <!--对象工厂-->
    <plugins/> <!--插件-->
    <environments> <!--配置环境-->
        <environment> <!--环境变量 -->
            <transactionManager/> <!--事务管理器-->
            <dataSource/> <!-- 数据源-->
        </environment>
    </environments>
    <databaseIdProvider/> <!--数据库厂商标识-->
    <mappers/> <!--映射器-->
</configuration>

例举几个,不一一解释了

  • properties是一个配置属性的元素,让我们能在配置文件的上下文中使用它。
  • 别名(typeAliases) 是一个指代的名称。因为我们遇到的类全限定名过长,所以我们希望用一个简短的名称去指代它,而这个名称可以在MyBatis 上下文中使用。
  • mappers常见有如下几种方法引入映射器
    • 文件路径引入
    • 包名引入
    • 类注册引入

2.2 MyBatis的映射器

常见元素如下:
在这里插入图片描述
在这里插入图片描述

着重说一下resultMap吧,这也是mybtais里最复杂的元素,它的作用是定义映射规则,级联的更新,定制类型转化器。

  <resultMap id="" type="">
    <constructor></constructor>
    <id></id> <!-- id代表resultMap的主键,而result代表其属性 -->
    <result></result>
    <association property=""></association> <!-- 一对一映射 -->
    <collection property=""></collection> <!-- 一对多映射 -->
  </resultMap>

constructor:constructor主要是用来配置构造方法,默认情况下mybatis会调用实体类的无参构造方法创建一个实体类,然后再给各个属性赋值,但是有的时候我们可能为实体类生成了有参的构造方法,并且也没有给该实体类生成无参的构造方法,这个时候如果不做特殊配置,resultMap在生成实体类的时候就会报错,因为它没有找到无参构造方法。

associationcollection:是mybatis支持级联的一部分,我们知道在级联中有一对一、一对多、多对多等关系,association主要是用来解决一对一关系的,collection主要是用来解决一对多关系的

2.3 Mybtais操作案例

public class SqlSessionUtils {

    private SqlSessionUtils(){}

    // 配置文件
    public static final String resource = "mybatis-config.xml";
	/**
	 * SqlSession是通过SqlSessionFactory来构造的,相当于维护一个连接池,当我们不停的进行查询的时候,		* 由于没有关闭连接,导致与数据库的连接数量达到了一个上限
	 */
    public static SqlSession getDefaultSqlSession() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        return sqlSessionFactory.openSession();
    }

    /**
     * SqlSessionManager通过动态代理技术+线程本地变量,升级了DefaultSqlSession的使用。
     * 解决了DefaultSqlSession自动关闭和线程安全问题
     * @return
     * @throws IOException
     */
    public static SqlSession getSqlSessionManage() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return SqlSessionManager.newInstance(inputStream);
    }
}
    @Test
    public void testUpdateUserInfo() throws IOException {
        SqlSession sqlSession = SqlSessionUtils.getDefaultSqlSession();
        UserInfo userInfo = new UserInfo();
        userInfo.setId(3);
        userInfo.setUserName("测试修改");
        userInfo.setPassword("111111");
        userInfo.setRegDate(new Timestamp(Instant.now().toEpochMilli()));
//        sqlSession.update("com.changda.mapper.UserInfoMapper.updateUserInfo");
        UserInfoMapper mapper = sqlSession.getMapper(UserInfoMapper.class);
        System.out.println(mapper.updateUserInfo(userInfo));
        sqlSession.commit();
    }


    @Test
    public void testUpdateUserInfo() throws IOException {
        SqlSession sqlSession = SqlSessionUtils.getSqlSessionManage();
        UserInfo userInfo = new UserInfo();
        userInfo.setId(3);
        userInfo.setUserName("测试修改");
        userInfo.setPassword("111111");
        userInfo.setRegDate(new Timestamp(Instant.now().toEpochMilli()));
        UserInfoMapper mapper = sqlSession.getMapper(UserInfoMapper.class);
        System.out.println(mapper.updateUserInfo(userInfo));
    }

3.Mybatis中的Dao接口和XML文件里的SQL是如何建立关系的?

  • 解析XML: 初始化SqlSessionFactoryBean会将mapperLocations路径下所有的XML文件进行解析
    • 创建SqlSource: Mybatis会把每个SQL标签封装成SqlSource对象,可以为动态SQL和静态SQL
    • 创建MappedStatement: XML文件中的每一个SQL标签就对应一个MappedStatement对象 ,并由 Configuration解析XML
  • Dao接口代理: Spring中的FactoryBean 和 JDK动态代理返回了可以注入的一个Dao接口的代理对象
  • 执行: 通过statement全限定类型+方法名拿到MappedStatement 对象,然后通过执行器Executor去执行具体SQL

四、SSM整合

第一步:导入相应的jar包

  <properties>
    <spring.version>5.1.8.RELEASE</spring.version>
  </properties>

  <dependencies>
    <!-- spring -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- mybatis 包 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.3</version>
    </dependency>

    <!--mybatis spring 插件 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.3</version>
    </dependency>

    <!-- mysql连接 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.21</version>
    </dependency>

    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
    </dependency>

    <!-- servlet -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>3.0-alpha-1</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <!-- slf4j日志包-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.21</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.21</version>
    </dependency>
  </dependencies>

第二步:写配置文件,将配置文件区分开

例举常见的一些xml配置,这里Spring3.0以后其实开始提倡JavaConfig的方式实现去XML配置,大家也不需要全部都记得,尤其Spring5.x版本之后,可以通过导入tomcat的内嵌jar包形式实现零xml配置启动,毕竟紧跟技术潮流嘛。

springmvc.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" 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">


    <!-- 配置IOC注解解析器 -->
    <context:component-scan base-package="com.zl.controller" />

    <!-- 配置MVC注解解析器 -->
    <mvc:annotation-driven/>

    <!-- 启动对@AspectJ注解的支持 -->
    <aop:aspectj-autoproxy/>

    <!-- 释放静态资源 -->
    <mvc:default-servlet-handler/>

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 配置逻辑视图的前缀 -->
        <property name="prefix" value="/views/" />
        <!-- 配置逻辑视图的后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>

</beans>
</beans>

applicationContext-dao.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"
       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">

    <!-- 加载配置文件 -->
    <context:property-placeholder location="classpath:jdbc.properties" />
    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="1"/>
        <property name="minIdle" value="1"/>
        <property name="maxActive" value="10"/>
        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait" value="10000"/>
        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000"/>
        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000"/>
        <property name="testWhileIdle" value="true"/>
        <!-- 这里建议配置为TRUE,防止取到的连接不可用 -->
        <property name="testOnBorrow" value="true"/>
        <property name="testOnReturn" value="false"/>
        <!-- 添加此处作用是为了在SQL监控页面显示sql执行语句,不配置不显示 -->
        <property name="filters" value="stat" />
    </bean>

    <!-- 配置 SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 数据库连接池 -->
        <property name="dataSource" ref="dataSource" />
        <!-- 加载 mybatis的全局配置文件 -->
        <property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml" />
        <!-- 自动扫描mapping.xml文件 -->
        <property name="mapperLocations" value="classpath:mapping/*.xml"></property>
    </bean>

    <!-- 配置 Mapper扫描 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 配置 Mapper扫描包 -->
        <property name="basePackage" value="com.zl.mapper" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>
</beans>

application-service.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"
       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">

    <!-- 配置 service扫描 -->
    <context:component-scan base-package="com.zl.service.impl" />

    <!-- 配置 线程池 -->
    <bean id="taskExecutor"
          class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="5" />
        <property name="maxPoolSize" value="10" />
        <property name="WaitForTasksToCompleteOnShutdown" value="true" />
    </bean>

    <!-- 扫描切点类组件 -->
    <context:component-scan base-package="com.zl.aop" />
</beans>

applicationContext-trans.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:tx="http://www.springframework.org/schema/tx"
       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/tx http://www.springframework.org/schema/tx/spring-tx.xsd   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 数据源 -->
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!--事务增强-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!--事务属性定义-->
        <tx:attributes>
            <tx:method name="list*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="validate*" read-only="true"/>
            <tx:method name="count*" read-only="true"/>
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <!-- 切面  匹配所有com.zl.service.impl包下的任意类和方法-->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.zl.service.impl.*.*(..))" />
    </aop:config>
</beans>

第三步:配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">

  <display-name>FruitSales</display-name>
  <welcome-file-list>
    <welcome-file>login.jsp</welcome-file>
  </welcome-file-list>

  <!-- 使用监听器加载 Spring配置文件 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
    
  <!-- 配置 spring -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/applicationContext*.xml</param-value>
  </context-param>
    
  <!-- 配置 SrpingMVC的前端控制器 -->
  <servlet>
    <servlet-name>springmvc</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>
    <!-- 标记容器在启动的时候就加载这个servlet -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!-- 配置所有以 /结尾的请求进入 SpringMVC -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!-- 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>

</web-app>

第四步:写测试用例

能看到helloWord就算搭建完成了

@Controller
public class UserInfoController {

    @RequestMapping("/login")
    public String login(){
        System.out.println("helloword!");
        return "index";
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/15204.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!