IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring、SpringMVC、MyBatis 的全注解方式整合 -> 正文阅读

[Java知识库]Spring、SpringMVC、MyBatis 的全注解方式整合

1、引语

  • 在学习注解方式整合 SSM 框架之前,一定要先学会 xml 配置文件整合(SSM 框架整合

  • 所谓使用全注解的方式进行 SSM 整合开发,就需要自定义类来替代 Spring、SpringMVC、MyBatis 的核心 xml 配置文件以及 web.xml,那么这些自定义的类 Tomcat 怎么就能知道他们用于配置框架的呢?就得从 web.xml 的替代配置类中入手分析

  • 在 Servlet3.0 环境中,Tomcat 会在类路径中查找 javax.servlet.ServletContainerInitializer 接口的实现类,如果找到就用该类来配置 Servlet 容器

  • 在 Spring 中提供了这个接口的实现,名为 SpringServletContainerInitializer,这个类反过来又会查找 WebApplicationInitializer 接口的实现类并将配置的任务交给 WebApplicationInitializer 的实现类来完成

  • 而 Spring3.2 及以上版本引入了一个便利的 WebApplicationInitializer 接口的基础实现类 AbstractAnnotationConfigDispatcherServletInitializer(没错,类名就是这么长),当我们的类继承了 AbstractAnnotationConfigDispatcherServletInitializer 并将其部署到 Servlet3.0 容器的时候,容器会自动发现它,并用它来配置 Servlet 上下文容器

由以上分析,使用全注解的方式配置 SSM,有以下几个核心步骤:

  1. 自定义类来继承 AbstractAnnotationConfigDispatcherServletInitializer 类以替代 web.xml,并在其中指定 Spring、SpringMVC 的配置类,指定 DispatcherServlet 的拦截路径,配置编码过滤器等
  2. 自定义类配置 Spring,容器如何知道这是一个配置类呢?Spring 为我们提供了一个便捷的注解 @Configuration,使用该注解标识一个类,容器就会将该类标识一个配置类并加载其中的配置
  3. 同理可自定义类来配置 SpringMVC、MyBatis(可直接在 Spring 的配置类中配置,此处为方便理解将其用单独的配置类进行配置)

1、web.xml 的替代配置类

package edu.whut.springbear.gather.config;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.Filter;

/**
 * web.xml 的替代配置类
 *
 * @author Spring-_-Bear
 * @datetime 2022-06-30 14:35 Thursday
 */
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     * 指定 Spring 的配置类
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfiguration.class};
    }

    /**
     * 指定 SpringMVC 的配置类
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfiguration.class};
    }

    /**
     * 指定 DispatchServlet 的拦截路径
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     * 过滤器
     */
    @Override
    protected Filter[] getServletFilters() {
        // 编码过滤器解决中文乱码
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter("UTF-8", true);
        // Http 请求方法过滤器以支持 RESTful 风格编程
        HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
        return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter};
    }
}

2、Spring 的配置类

  1. 使用 @Import 注解可引入其它的配置类如 MyBatis 的配置类
  2. 使用 @PropertySource 注解可引入 .properties 配置文件如引入数据库配置文件
  3. 使用 @ComponentScan 注解扫描包中的组件(一定不要扫描 Spring 配置类所在的包,否则报错),组件扫描的策略是:除了 Controller 组件留给 SpringMVC 扫描,其余组件均有 Spring 扫描。言外之意就是 Spring 处理不扫描 controller 包,其余所有包均可扫描(不可以同时在 Spring 和 SpringMVC 中扫描 controller 包,否则报错=)
package edu.whut.springbear.gather.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;

import javax.sql.DataSource;


/**
 * Spring 的配置类以替代 applicationContext.xml
 *
 * @author Spring-_-Bear
 * @datetime 2022-06-30 14:36 Thursday
 */
@Configuration
@Import(MyBatisConfiguration.class)
@PropertySource("classpath:application.properties")
@ComponentScan(basePackages = {"edu.whut.springbear.gather.pojo", "edu.whut.springbear.gather.mapper",
        "edu.whut.springbear.gather.service", "edu.whut.springbear.gather.util",
        "edu.whut.springbear.gather.exception", "edu.whut.springbear.gather.interceptor"})
public class SpringConfiguration {
    /**
     * 读取 application.properties 中的配置信息
     */
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    /**
     * 配置数据源
     */
    @Bean
    public DataSource getDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driver);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        return druidDataSource;
    }
}

3、SpringMVC 的配置类

  1. 使用 @EnableWebMVC 注解开启注解驱动以支持 SpringMVC 的一些高级功能
  2. 使用 @ComponentScan 注解扫描 controller 组件
  3. 在 SpringMVC 的配置类中配置一些常用的组件如:默认 Servlet 处理静态资源、Thymeleaf 视图解析器、视图控制器实现、文件上传解析器、拦截器等
package edu.whut.springbear.gather.config;

import edu.whut.springbear.gather.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ITemplateResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

import javax.servlet.ServletContext;


/**
 * SpringMVC 的配置类
 *
 * @author Spring-_-Bear
 * @datetime 2022-06-30 14:36 Thursday
 */
@Configuration
@EnableWebMvc
@ComponentScan(value = {"edu.whut.springbear.gather.controller"})
public class SpringMvcConfiguration implements WebMvcConfigurer {
    /**
     * 配置默认 Servlet 处理静态资源
     */
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    /**
     * 以下三个方法均用于配置 Thymeleaf 视图解析器
     * ITemplateResolver -> SpringTemplateEngine -> ViewResolver
     */
    @Bean
    public ITemplateResolver templateResolver() {
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        assert webApplicationContext != null;
        ServletContext servletContext = webApplicationContext.getServletContext();
        assert servletContext != null;
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setCharacterEncoding("UTF-8");
        templateResolver.setTemplateMode(TemplateMode.HTML);
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);
        return templateEngine;
    }

    @Bean
    public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setCharacterEncoding("UTF-8");
        viewResolver.setTemplateEngine(templateEngine);
        return viewResolver;
    }

    /**
     * 视图控制器(不需要处理逻辑,仅仅实现页面跳转时使用)
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
    }

    /**
     * 文件上传解析器:需要引入 commons-fileupload 依赖
     */
    @Bean
    public CommonsMultipartResolver multipartResolver() {
        return new CommonsMultipartResolver();
    }

    /**
     * 拦截器:需要自定义类实现 HandlerInterceptor 接口
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 登录拦截器:拦截除 / 首页外的所有请求
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/");
    }
}

4、MyBatis 的配置类

在 MyBatis 的配置类设置数据源并配置一些常用的功能,如:以包为单位为 POJO 类设置别名、开启自动驼峰命名转换、设置分页插件等

package edu.whut.springbear.gather.config;

import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.Properties;


/**
 * MyBatis 的配置类
 *
 * @author Spring-_-Bear
 * @datetime 2022-06-30 15:07 Thursday
 */
@Configuration
public class MyBatisConfiguration {
    /**
     * SQL 会话工厂
     */
    @Bean("sqlSessionFactory")
    public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 设置数据源
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 以包为单位设置 POJO 类别名(默认为类名)
        sqlSessionFactoryBean.setTypeAliasesPackage("edu.whut.springbear.gather.pojo");
        // 开启自动驼峰命名转换(Java 成员变量与数据库表字段之间的自动转换)
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        sqlSessionFactoryBean.setConfiguration(configuration);
        // 设置分页插件
        sqlSessionFactoryBean.setPlugins(new Interceptor[]{getPageInterceptor()});
        return sqlSessionFactoryBean;
    }

    /**
     * 指定 Mapper 接口所在的包
     */
    @Bean
    public MapperScannerConfigurer getMapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("edu.whut.springbear.gather.mapper");
        return mapperScannerConfigurer;
    }

    /**
     * 设置分页插件:需引入 com.github.pagehelper 依赖
     */
    @Bean
    public PageInterceptor getPageInterceptor() {
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        properties.setProperty("value", "true");
        pageInterceptor.setProperties(properties);
        return pageInterceptor;
    }
}

5、结语

至此,注解方式整合 SSM 常用配置基本完成,剩下的基本就是编写业务代码处理自己的业务逻辑,不再赘述。可参考个人全注解 SSM 开源项目【两码一查】

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:07:52  更:2022-07-17 16:12:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 15:30:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码