回忆

在几年前的工作中,接触springboot这个技术有过五六个月。收到springMVK开发习惯的影响,几乎没有兴趣深入了解这门技术的便利性,只是快速的用自己熟悉的方式方法将安排的工作做完。唯一且最大的好处就是:一个POM引入依赖,一个@SpringBootApplication,再run main方法,剩下基本就是业务处理。

思进

至今,有两三年没有去关注技术的发展了。偏于对技术的热爱,又一次拾起曾经丢下的东西,第一感觉就是:新奇+熟悉。
令我新奇的是:微服务的发展如此迅猛,技术的更新与支持氛围如此之浓厚,以至于 spring社区 将springboot升级为顶级项目。再者就是对于维护和支持

今年11月24日再度发布新版本 【3.0.x】,而且老版本【2.3.x】今年8月20日维护到期。
而令我熟悉感爆棚的是:这种快捷方式仍然是以前的画面

还有就是博客园平台一如既往对技术博客的排给,无论是入门还是进阶,都能够准确找到相关博客文章。

开始

进入主题,springboot技术知识点温习与汇总。

首先,得有个得力的IDE工具

目前开发者应用最多的有 IdeaEclipse 。业界公认好用的是Idea,但收费,也有社区版免费使用,功能相对就没那么全面了(笔者使用的是社区版 2022.2-Windows ZIP Archive(zip))。

IDEA下载,如下图

Eclipse下载。

而Eclipse是开源免费的版本,虽然没有Idea那么强大好用,但插件支持非常多。可以下载解压版

对于工具,够用且能够满足日常需要即可。

第二,需要配置好开发环境

JDK下载

选择自己合适的 JDK 版本,但由于国外网站访问比较慢,笔者推荐使用镜像站下载,如 injdk

在诸多JDK版本中,jdk8,jdk11,jdk17是长期维护的稳定版本,推荐使用 。

maven下载配置

如果需要maven,那么可以配置一下。首先需要下载 maven

接下来,就需要在开发环境配置。首先解压你的 ZIP文件到指定目录 。

打开 idea 工具,依次 【文件】-【设置】-【Maven】。

再找到 【Maven主路径(H)】,点击 【...】打开【选择Maven主目录】,选择刚才解压的maven文件夹。

编写maven配置文件setting.xml,需要添加如下两项 :

setting.xml配置
#指定本地仓库目录
<localRepository>F:/study/project/repo</localRepository>
#可定制maven仓库
<mirror>
	<id>central-repos1</id>  
	<mirrorOf>*</mirrorOf>
	<name>Central Repository 2</name>  
	<url>https://repo1.maven.org/maven2/</url>
</mirror>
#指定JDK版本
<profile> 
      <id>jdk-1.8</id>  
      <activation>
        <activeByDefault>true</activeByDefault>
        <jdk>1.8</jdk>  
      </activation>  
        
      <properties>  
        <maven.compiler.source>1.8</maven.compiler.source>  
        <maven.compiler.target>1.8</maven.compiler.target>  
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>  
      </properties>   
    </profile> 
  </profiles>

现在就可以在idea中指定自定义的maven配置了。

最后,需要再确认一下【本地仓库(R)】是否正确。完成以后新建一个maven项目,测试是否配置成功。

如果配置的本地仓库目录不断开始下载pom依赖,说明配置成功。

Git下载及使用教程推荐

同样,如果需要代码版本控制,可以下载 Git

安装就不累述了,可以查找 相关教程。安装好后,可以在项目目录下执行 git相关命令

git使用笔者就先不写了,接下来基本可以开始springboot开发了。

springboot项目构建

再度理解一下springboot概念

特性

1.使用 “约定优先于配置”(COC,Convension Over Configuration)的设计理念。
2.spring-boot-starter 自动配置依赖模块供我们开箱即用。
3.对主流框架进行无配置集成,自动整合第三方框架。
4.可独立运行 Spring 项目,Spring Boot 可以 jar 包形式独立运行。
使用 java -jar 命令或者在项目的主函数中执行 main 函数就可以成功运行项目。
5.纯 Java 配置,没有代码生成,也不需要 XML 配置。
6.提供了很多插件让我们开箱即用,能够快速的搭建一个 Spring 项目,很少配置就
能运行一个 JavaEE 项目。

缺点

1.自动化配置,导致出现问题时比较难定位。
2.版本迭代速度过快,一些模块改动太大。
3.集成度过高,想了解底层成本较大。

Spring Boot 是通过 Spring Framework 的 @Enable 注解模块驱动实现的全新自动化配置解决方案。为快速启动且最小化配置的 Spring 应用而设计,并且它具有用于构建生产级别应用的一套固化的视图。

进阶

maven构建

  • 相关依赖请移步 mvnrepository
  • spring-boot-starter-parent,pom(project object model)指定后,即为springboot项目,且相关兼容版本的依赖全部导入。
  • spring-boot-starter,普通的springboot项目,开箱即用,适合一次性响应结果场景。
  • spring-boot-starter-web,开发web项目使用,可以使用URL(Uniform Resource Locator)进行访问,并且使用restful风格,返回JSON数据结构。
  • spring-boot-starter-test,单元测试使用,配合idea插件使用非常方便。
  • spring-boot-autoconfigure,springboot配置文件,可以时properties和yml两种类型。
  • spring-boot-configuration-processor,配置文件的提示插件。
  • spring-boot-starter-actuator,系统健康监控器,用于检测系统的健康情况、当前的Beans、系统的缓存等。
  • spring-boot-starter-data-jpa,数据层访问提供的注解支持插件,orm框架的连接件。
  • spring-boot-starter-security,应用框架的权限插件,用于控制业务逻辑,保障数据访问安全。
  • spring-boot-starter-validation,Java bean参数合法校验。
  • spring-boot-starter-data-redis,整合redis缓存驱动框架,使用其RedisTemplate操作数据信息。
  • spring-boot-starter-logging,日志框架,记录系统运行信息并输出log文件。
  • spring-boot-starter-thymeleaf,一款强大的页面渲染插件,与vue非常相似。
  • spring-boot-starter-activemq,消息中间件,提供广播和消息队列方式两种方式。

springboot web常用注解

  • @SpringBootApplication,项目启动注解,包含@EnableAutoConfiguration,@ComponentScan注解。
  • @RestController,控制器注解,包含@Controller,@ResponseBody。
  • @Autowired,bean注解,自动注入,相当于bean的实例化。在spring的bean工厂会自动生产多个该bean对象,提高访问效率。
  • @PathVariable,访问路径变量,相当于该变量也是URL的一部分。
  • @GetMapping,请求路径,指定请求方式为GET类型。且包含@RequestMapping 。
  • @PostMapping,请求路径,指定请求方式为POST,传参更加安全。且包含@RequestMapping 。
  • @RequestParam,请求参数,可以是任意类型的object 。
  • @ResponseStatus,响应状态码,在org.springframework.http.HttpStatus具体定义。
  • @Service,一般用于修饰service层。
  • @Repository,数据层注解,修饰的DAO或者repositories类会被ComponetScan发现并配置,同时也不需要为它们提供XML配置项。
  • @Bean:该注解标注等价于XML中配置的bean。
  • @Value:为bean配置属性的值。
  • @ExceptionHandler,全局异常处理。用于方法。

MySQL与mybatis支持

  • MySQL依赖 mysql-connector-java
  • MySQL配置(注意缩进和空格,即yaml语法)
     spring :
       datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://hosturl:port/db_name?useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&useSSL=false
        username: ***
        password: ***
    
  • mybatis依赖mybatis-spring-boot-startermybatis-plus-boot-starter
  • mybatis配置
       mybatis: 
          type-aliases-package: com.*.*.*mapper
          configuration: 
            map-underscore-to-camel-case: true
    
  • mysql数据库的应用(mybatis完全支撑)
  • @MapperScan 对指定package进行扫描,最好注解在启动类@SpringBootApplication一起,例如 @MapperScan(value = {"com.*.*.*mapper","org.*.*.*"})
  • @Results@Result(property = "beanPropertyName", column = "tableColumnName")
  • @Insert("原生SQL") 注入SQL,占位符参数使用#{beanPropertyName}进行传递
  • @Update("SQL") ,@Delete("SQL"),@Select("SQL")

Redis缓存的支撑

  • 依赖 spring-boot-starter-data-redis

  • 配置

      redis:
        database: 0
        host: localhost
        port: 6379
        password: 
        timeout: 10s
      
    
  • RedisConfig全部代码

      package com.m.m.m;
    
      import com.fasterxml.jackson.annotation.JsonAutoDetect;
      import com.fasterxml.jackson.annotation.PropertyAccessor;
      import com.fasterxml.jackson.databind.ObjectMapper;
      import org.springframework.cache.CacheManager;
      import org.springframework.cache.annotation.CachingConfigurerSupport;
      import org.springframework.cache.annotation.EnableCaching;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.data.redis.cache.RedisCacheConfiguration;
      import org.springframework.data.redis.cache.RedisCacheManager;
      import org.springframework.data.redis.cache.RedisCacheWriter;
      import org.springframework.data.redis.connection.RedisConnectionFactory;
      import org.springframework.data.redis.core.*;
      import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
      import org.springframework.data.redis.serializer.StringRedisSerializer;
    
      import java.time.Duration;
    
      @Configuration
      @EnableCaching
      public class RedisConfig extends CachingConfigurerSupport {
      	@Bean
      	public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
      		RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
      				.entryTtl(Duration.ofHours(240)); // 设置缓存有效期
      		return RedisCacheManager
      				.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
      				.cacheDefaults(redisCacheConfiguration).build();
      	}
    
      	/**
      	 * retemplate相关配置
      	 * @param factory
      	 * @return
      	 */
      	@Bean
      	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
    
      		RedisTemplate<String, Object> template = new RedisTemplate<>();
      		// 配置连接工厂
      		template.setConnectionFactory(factory);
    
      		//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
      		Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
    
      		ObjectMapper om = new ObjectMapper();
      		// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
      		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
      		// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
      		om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
      		jacksonSeial.setObjectMapper(om);
    
      		// 值采用json序列化
      		template.setValueSerializer(jacksonSeial);
      		//使用StringRedisSerializer来序列化和反序列化redis的key值
      		template.setKeySerializer(new StringRedisSerializer());
    
      		// 设置hash key 和value序列化模式
      		template.setHashKeySerializer(new StringRedisSerializer());
      		template.setHashValueSerializer(jacksonSeial);
      		template.afterPropertiesSet();
    
      		return template;
      	}
    
      	/**
      	 * 对hash类型的数据操作
      	 *
      	 * @param redisTemplate
      	 * @return
      	 */
      	@Bean
      	public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
      		return redisTemplate.opsForHash();
      	}
    
      	/**
      	 * 对redis字符串类型数据操作
      	 *
      	 * @param redisTemplate
      	 * @return
      	 */
      	@Bean
      	public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
      		return redisTemplate.opsForValue();
      	}
    
      	/**
      	 * 对链表类型的数据操作
      	 *
      	 * @param redisTemplate
      	 * @return
      	 */
      	@Bean
      	public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
      		return redisTemplate.opsForList();
      	}
    
      	/**
      	 * 对无序集合类型的数据操作
      	 *
      	 * @param redisTemplate
      	 * @return
      	 */
      	@Bean
      	public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
      		return redisTemplate.opsForSet();
      	}
    
      	/**
      	 * 对有序集合类型的数据操作
      	 *
      	 * @param redisTemplate
      	 * @return
      	 */
      	@Bean
      	public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
      		return redisTemplate.opsForZSet();
      	}
      }
    
    
  • 操作redis缓存数据库(相对于关系型数据库系统简单多了)

        @Autowired
        RedisTemplate redisTemplate;
    
        @Test
        public void redisTest(){
      	ValueOperations<String, SysUser> operations = redisTemplate.opsForValue();
      	operations.set("5225552d4f4s4f488e5f222a2",new SysUser("dkkfdke332kld","号","55f2d5e5e5-df4d4f4d4==",false,new Date()));
    
      	System.out.println(operations.get("5225552d4f4s4f488e5f222a2"));
        }
    

Junit单元测试

  • 相关注解用法
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = com.m.m.M.class)
    @SpringBootConfiguration
    `public class DBTest {
        @Test
        访问修饰符  方法返回值类型 方法名(){
          //方法体内容
          ......
        }
    }`
    
  • 执行
    • 鼠标右键
    • 查看运行结果

持续更新中。。。