SSM 整合

  • 父子容器
    • 父子容器的配置文件建议
    • 子容器的加载创建
    • 父容器的加载创建
  • MyBatis 补充
    • mybatis-config.xml
  • Maven 补充
  • SSM 整合 - 纯注解
    • Initializer 取代 web.xml
    • SpringConfig
    • SpringMVCConfig
      • Interceptor - 添加拦截器
      • ViewResolver - 添加视图解析器
      • MultipartResolver - 添加 multipart 参数解析
      • Converter - 类型转换器
      • MessageConverters - 解决编码问题
      • DefaultServletHandler

Java 从 0 到架构师目录:【Java从0到架构师】学习记录

Gitee 代码:https://gitee.com/szluyu99/mj_java_frame/tree/master/03_SpringMVC


本章涉及的完整代码:SSM 整合 - XML 示例代码

前面学习过 Spring + MyBatis 的整合,还需要整合 SpringMVC

父子容器

SpringMVC 本身属于 Spring 的一部分?还需要做整合操作?

  • 需要!

目前存在的问题:所有的 bean 都存储在同一个 IoC 容器中

  • 无法避免在 service 注入 controller 等问题

解决方案:父子容器



特点:

  • 父容器和子容器是相互隔离的,它们内部可以存在名称相同的 bean
  • 子容器可以访问父容器中的 bean,而父容器不能访问子容器的 bean
  • 调用子容器的 getBean 方法,会沿着当前容器向父容器进行查找,直到找到对应的 bean 为止
  • 子容器中可以通过注入父容器中的 bean,而父容器中无法注入子容器中的 bean

优点:

  • 采用父子容器可以避免依赖层次混乱(service 注入 controller)
  • 将相互不关心的东西隔开,可以有效避免一些不必要的错误,而父子容器加载的速度也会快一些

父子容器的配置文件建议

子容器的配置文件:dispatcherServlet.xml

  • controller、SpringMVC 专用的一些 bean
<context:component-scan base-package="com.mj.controller"/>

父容器的配置文件:applicationContext.xml

  • service、dao、其他(非 SpringMVC 专用的 bean,共用的 bean 等)
<context:component-scan base-package="com.mj.service"/>

子容器的加载创建

在 web.xml 中配置:

<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:dispatcherServlet.xml</param-value></init-param><load-on-startup>0</load-on-startup>
</servlet><servlet-mapping><servlet-name>DispatcherServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

父容器的加载创建

在 web.xml 中配置:

<context-param><param-name>contextConfigLocation</param-name><!-- 父容器 --><param-value>classpath:applicationContext.xml</param-value>
</context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

MyBatis 补充

如果将 Mapper 文件跟 dao 放在相同目录下,且文件名跟 dao 一样:

  • 那么通过 MapperScannerConfigurer 就可以找到 Mapper 文件
  • 不需要再配置 SqlSessionFactoryBean 的 mapperLocations 属性

可以设置 SqlSessionFactoryBean 的 configLocation 属性,指定 MyBatis 核心配置文件的位置

<!-- 设置MyBatis核心配置文件的位置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>

mybatis-config.xml

如果对于 mybatis 有些设置需要进行配置,还是需要写到 mybatis-config.xml 中,再在 Spring 中读取:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings>
</configuration>

Maven 补充

默认情况下,Maven 并不会将源代码文件夹中的配置文件(propertis,xml 等)打包

若想打包源代码文件夹中的配置文件,需要进行额外的配置:

<build><resources> <!-- 说明资源的位置(哪些东西算是资源) --><resource> <!-- 第一个位置 --><directory>src/main/resources</directory></resource><resource> <!-- 第二个位置 --><directory>src/main/java</directory><includes> <!-- 设置打包包含的文件 --><include>**/*.properties</include><include>**/*.xml</include></includes></resource></resources>
</build>

SSM 整合 - 纯注解

Initializer 取代 web.xml

新建一个类,继承 AbstractAnnotationConfigDispatcherServletInitializer:示例代码

public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {/*** 父容器的配置类*/@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class[]{SpringConfig.class};}/*** 子容器的配置类(SpringMVC相关的配置类)*/@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[]{SpringMVCConfig.class};}/*** 配置DispatcherServlet的url-pattern*/@Overrideprotected String[] getServletMappings() {return new String[]{"/"};}@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {// 需要调用supersuper.onStartup(servletContext);// 添加FilterFilterRegistration.Dynamic encodingFilter = servletContext.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class);encodingFilter.setInitParameter("encoding", "UTF-8");encodingFilter.addMappingForUrlPatterns(null, false, "/*");}}

AbstractAnnotationConfigDispatcherServletInitializer 的本质:

  • 最终是实现了 WebApplicationInitializer 接口
  • 项目部署到 web 容器时,会初始化实现了 WebApplicationInitializer 接口的实例,并调用它的 onStartup 方法

实现 WebApplicationInitializer 接口:

SpringConfig

SpringConfig 可以不需要再写 @Configuration:示例代码

@ComponentScan("com.mj.service")
@EnableWebMvc
public class SpringConfig {}

SpringMVCConfig

SpringMVCConfig 可以不需要再写 @Configuration:示例代码

@ComponentScan("com.mj.service")
public class SpringMVCConfig {}

Interceptor - 添加拦截器

@Autowired
private MyInterceptor myInterceptor;/*** 添加拦截器,相当于 <mvc:interceptors>*/
@Override
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor).addPathPatterns("/**").excludePathPatterns("/asset/**");
}

ViewResolver - 添加视图解析器

@Bean
public InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix("/WEB-INF/page/"); // 前缀resolver.setSuffix(".jsp"); // 后缀return resolver;
}

MultipartResolver - 添加 multipart 参数解析

需要依赖:

<!-- commons-fileupload: 解析Multipart参数 -->
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version>
</dependency>
@Bean
public CommonsMultipartResolver multipartResolver() {CommonsMultipartResolver resolver = new CommonsMultipartResolver();resolver.setDefaultEncoding("UTF-8");return resolver;
}

Converter - 类型转换器

可以添加一个时间转换器,实现对前端传来的任意格式的时间字符串进行解析:

@Autowired
private DateConverter dateConverter;@Override
public void addFormatters(FormatterRegistry registry) {registry.addConverter(dateConverter);
}
@Component
public class DateConverter implements Converter<String, Date> {@Overridepublic Date convert(String source) {try {return new SimpleDateFormat("yyyy-MM-dd").parse(source);} catch (ParseException e) {e.printStackTrace();return null;}}
}

MessageConverters - 解决编码问题

取代了 XML 中的:<mvc:message-converters>

/*** 相当于 <mvc:message-converters>*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {// 设置返回的普通字符串的编码StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();stringConverter.setDefaultCharset(StandardCharsets.UTF_8);converters.add(stringConverter);// 设置返回的JSON数据的编码MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();jsonConverter.setDefaultCharset(StandardCharsets.UTF_8);converters.add(jsonConverter);
}

DefaultServletHandler

取代了 XML 配置中的:<mvc:default-servlet-handler/>

/*** 相当于<mvc:default-servlet-handler/>* 用以处理静态资源*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {configurer.enable();
}

【Java从0到架构师】SSM 整合(XML、纯注解)相关推荐

  1. 【Java从0到架构师】Spring - 整合 MyBatis

    整合 MyBatis 整合 MyBatis - 依赖 整合 MyBatis - 数据源 整合 MyBatis - SqlSessionFactoryBean 整合 MyBatis - MapperSc ...

  2. 【Java从0到架构师(1),Java中高级面试题总结(全面)

    JSP 九大内置对象 MySQL 基础 + 多表查询 [Java从0到架构师]MySQL 基础 MySQL MySQL 的使用步骤 数据库的内部存储细节 GUI 工具 SQL 语句 DDL 语句 DD ...

  3. 【Java从0到架构师】SpringCloud - Sleuth、Zipkin、Config

    SpringCloud 链路追踪组件 Sleuth Zipkin 分布式配置中心 - Config Git + Config 分布式配置中心 Java 从 0 到架构师目录:[Java从0到架构师]学 ...

  4. 【Java从0到架构师】SpringCloud - Eureka、Ribbon、Feign

    SpringCloud 分布式.微服务相关概念 微服务框架构选型 SpringCloud 概述 服务注册与发现 - Eureka 案例项目 Eureka 自我保护机制 微服务调用方式 - Ribbon ...

  5. 【Java从0到架构师】Redis 应用 - Jedis 基本使用、使用缓存的用户登陆、缓存常见问题

    Redis 原理与实战 Jedis 基本使用 Jedis 连接 Redis 服务器 Jedis 使用 pipeline Jedis 发布订阅 Jedis 使用 bitmap Jedis 使用 Hype ...

  6. 【Java从0到架构师】SpringBoot - 入门_配置文件_YAML

    SpringBoot - 入门_配置文件_YAML SpringBoot - 入门 @SpringBootApplication 可运行 jar - spring-boot-maven-plugin ...

  7. 【Java从0到架构师】Spring - 纯注解开发

    纯注解开发 纯注解开发 - AOP 纯注解开发 - 整合 MyBatis 纯注解开发 - 事务管理 JSR 注解 JSR 注解 - @Resource.@Inject JSR 注解 - @PostCo ...

  8. 【Java从0到架构师】Spring - IoC 控制反转、DI 依赖注入

    IoC 控制反转.DI 依赖注入 Spring 简介 Spring 基本使用 - IoC 容器 依赖注入 (Dependency Injection) 基于 setter 的注入 - 自定义对象 be ...

  9. 【Java从0到架构师】SpringCloud - Hystrix、Zuul

    SpringCloud 基本概念 熔断和降级 服务雪崩效应 服务熔断与降级 - Hystrix SpringBoot 集成 Hystrix 熔断降级服务异常报警通知 重点属性 - 熔断隔离策略.超时时 ...

最新文章

  1. 2022-2028年中国PGA树脂行业全景调研及投资前景展望报
  2. iOS 5中的strong和weak关键字
  3. oracle初始安装大小
  4. devstack部署openstack流程与相关问题的记录(ubuntu 16.04)
  5. CentOS 7.0安装Nvidia驱动
  6. python用递归方式实现最大公约数_关于python最大递归深度 - 998
  7. android源代码
  8. Pyhton函数式编程简介(四)装饰器
  9. java批量提取文件夹名称_bat 批量提取指定目录下的文件名
  10. 信息学奥赛一本通 1069:乘方计算 | OpenJudge NOI 1.5 13
  11. 使用Python批量替换指定目录所有文件中的指定文本
  12. 汇编指令对应的机器码_汇编语言输出“welcome to you!”
  13. 基于java的药品管理系统_基于Java药品管理系统
  14. SqlMap免Python环境绿色版下载
  15. 把antd组件的英文切换为中文
  16. 无法打开键,请验证您对该键拥有足够的访问权限
  17. 云原生发展趋势-2022
  18. Python中随机数种子的作用及使用
  19. Android Proguard混淆详解
  20. SurroundDepth:自监督多摄像头环视深度估计

热门文章

  1. 微信小程序为什么会成为了实体店“上线”的最优选择?
  2. 又到年关,年终奖你能拿多少?
  3. 短视频的运营团队分为三种
  4. MATLAB中的for循环
  5. Java - package和import
  6. SpringSecurity入门
  7. sql还原数据库备份数据库_如何获取SQL数据库还原历史记录
  8. vlf 用法_什么是SQL虚拟日志文件(又名SQL Server VLF)?
  9. 如何使用PowerShell处理SQL Azure数据库
  10. 如何在SQL Server中分析存储子系统性能