2

Spring-Boot 学习笔记

1 Spring-Boot 介绍

1.1 什么是Spring-Boot

  • Spring-Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。个人理解来说Spring-Boot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,Spring-Boot整合了其他相关联框架。
  • Spring-Boot 基于Spring框架,而Spring-Cloud基于Spring-Boot,为微服务体系开发中的架构问题,提供了一整套的解决方案——服务注册与发现,服务消费,服务保护与熔断,网关,分布式调用追踪,分布式配置管理等。
  • Spring-Boot 四大特性:自动配置起步依赖Actuator命令行界面(CLI)

1.2 为什么要使用Spring-Boot

  • 区别于Spring-Boot以前的Spring和其他框架的整合例如Mybatis,Shiro等都需要配置文件,项目中的配置文件越来越多,也越来越繁琐。项目中常常因为配置文件出错的原因,导致项目运行出错。
  • 而Spring-Boot可以说就是为了解决繁杂配置而出现的解决方案。Spring-Boot理念可以理解为:约定大于配置。快速整合第三方框架,减少甚至不需要配置文件,解决了以往的Spring框架下的弊端。
  • 因为配置文件少了,代码变少了,第三方框架带来的烦恼变少了,对于一个开发团队来说,更加利于开发,后期维护也更加简单。
  • 要使用Spring-Cloud前应该掌握Spring-Boot
1.2.1 Spring-Boot 自动配置

传统的Spring web项目配置需要经过以下步骤:

  • 1)配置web.xml,加载Spring和Spring MVC
  • 2)配置数据库连接、配置Spring事务
  • 3)配置加载配置文件的读取,开启注解
  • 4)配置日志文件
  • 配置完成之后部署tomcat 调试

但是针对一些单一业务需求的项目,例如该项目只是实现一个邮件收发,表格导出等单一功能,配置步骤便显得麻烦。

Spring-Boot的自动配置则能够简化很多配置,减少传统开发步骤,直接开展项目。

1.2.2 Spring-Boot 起步依赖
  1. Spring-Boot启动时回去导入spring-boot-autoconfigure包下META-INF/spring.factories配置文件
  2. 根据XxxxAutoConfiguration配置类的条件注解@Conditional判断当前环境中是否满足XxxxAutoConfiguration的注解条件,如果满足,则自动向Spring IOC 容器中注入bean
1.2.3 Spring-Boot Actuator
  • Spring-Boot为了改善传统Spring应用繁杂的配置内容,采用了包扫描和自动化配置的机制,加载了原来在xml文件中的内容。自动配置有利有弊,有利的地方是让代码看上去更加简洁,反面则造成了分析应用中资源和实例的各种关系变得困难(实例创建和依赖关系等信息都被离散到了各个配置类的注解上)
  应用配置类:获取应用程序中加载的应用配置、环境变量、自动化配置报告等与Spring-Boot应用密切相关的配置类信息。
  
  度量指标类:获取应用程序运行过程中用于监控的度量指标,比如:内存信息、线程池信息、HTTP请求统计等。
  
  操作控制类:提供了对应用的关闭等操作类功能。
  • Actuator这类端点的出现意义就是为了帮助我们轻松的获取一系列关于Spring 应用配置内容的详细报告,比如:自动化配置的报告、Bean创建的报告、环境属性的报告等。
  • Actuator提供了以下监控方式

图片描述

  • Actuator 提供了 13 个接口,具体如下表所示

图片描述

  • 通过在配置文件中加入 management.security.enabled=false

例如:
图片描述
图片描述

1.2.4 Spring-Boot CLI

Spring-Boot CLI是一个命令行工具,可用于快速搭建基于Spring的原型。它支持运行Groovy脚本,这也就意味着你可以使用类似Java的语法,但不用写很多的模板代码。

  • 首先下载Spring-Boot CLI

https://docs.spring.io/spring...

图片描述

  • 配置环境变量

在PATH 中配置Spring-Boot CLI文件夹下bin的路径:
D:spring-boot-cli-1.5.9.RELEASE-binspring-1.5.9.RELEASEbin

  • 打开CMD查看是否安装成功

输入 spring --version (注意是--)

图片描述

  • 使用命令初始化项目

spring init --build=maven --java-version=1.8 --dependencies=web --packaging=jar --boot-version=1.5.9.RELEASE --groupId=com.example.demo --artifactId=javen

图片描述

--build:表示项目构建工具maven,也可以选择gradle
--java-version:表示JDK版本
--dependencies=web:表示依赖web插件
--packaging:表示打包程序方式
--boot-version:选择 spring boot的版本
--groupId:maven的groupId
--artifactId:maven的artifactId

图片描述

将生成的javan.zip导入eclipse(STS)中即可

1.3 更简洁的报错信息

图片描述
Spring-Boot相比于以前的控制台报错信息,更加人性化和简洁。

2 Spring-Boot 环境要求

  • 默认情况下,Spring-Boot 1.3.0 Build-snapshot 需要Java 7 以及Spring框架 4.1.3或以上,如果在Java 6下使用Spring-Boot,需要添加额外的配置。
  • 虽然可以在Java 6 和 java 7下使用Spring-Boot,但是官方建议在Java 8下使用Spring-Boot
  • 构建环境明确支持有Maven(3.2+)和Gradle(1.12+)。

2.1 Spring-Boot 内嵌servlet 容器

Spring-Boot内嵌容器支持开箱即用(out of the box)
图片描述

也可以使用Spring-Boot应用部署到任何兼容Servlet 3.0+的容器。

3 创建 Spring-Boot 项目

3.1 三种创建Spring-Boot项目的方式:

进行项目名称等设置并选择版本、依赖。然后会下载这个项目的压缩文件,解压后,使用 eclipse,Import -> Existing Maven Projects -> Next ->选择解压后的文件夹-> Finsh 成功导入该项目

  • 2) 使用Spring-Boot 插件,在eclipse中new一个 Spring starter project,并选择需要的依赖。(第一次构建会很慢)
  • 3) 用maven构建项目

上面 1)、2)的构建方式中生成的pom.xml文件中默认有两个模块:

  • spring-boot-starter :核心模块,包括自动配置支持、日志和yml;
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
</parent>
  • spring-boot-starter-test :测试模块,包括JUnit、Hamcrest、Mockito。
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
</dependency>

3.2 Spring-Boot热部署:

  • 只用在pom.xml里面依赖devtools即可
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <optional>true</optional>
</dependency>
3.2.1 Spring-Boot热部署重新编译类文件
  • 热部署指的是:当我们修改了一个java类的时候,我们只需要重新编译一下,Spring-Boot的就会重启了。因为devtools会监听classpath下的文件变动,所以当java类重新编译的时候,devtools会监听到这个变化,然后就会重新启动Spring-Boot。这个重启是非常快的一个过程。因为在Spring-Boot中有两个类加载器,一个是加载工程外部资源的,如jar包,还有一个类加载器是用来加载本工程的class的。所以在重启Spring-Boot的时候只加载本工程的class文件。
3.2.2 Spring-Boot热部署监听文件夹的变化
  • 如果你不想重新编译java类的话,还有一种方式用来让Spring-Boot重启,那就是让devtools监听文件夹的变化:比如我们想让com.example.springboot这个文件夹下的文件改变的时候,重新启动Spring-Boot,那么我们只要在application.properties中添加这样一句话就行了:spring.devtools.restart.additional-paths=com\example\springboot
3.2.3 Spring-Boot热部署页面热部署
  • devtools可以实现页面热部署,即页面修改后会立即生效。你可以在application.properties文件中配置spring.thymeleaf.cache=false来实现这个功能。

3.3 Spring-Boot Maven插件:

3.3.1 Spring-Boot maven插件作用:
  • Spring-Boot的Maven插件(spring-boot-maven-plugin)能够以Maven的方式为应用提供Spring-Boot的支持,即为Spring-Boot应用提供了执行Maven操作的可能。
  • spring-boot-maven-plugin能够将Spring-Boot应用打包为可执行的jar或war文件,然后以通常的方式运行Spring Boot应用。
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
              <fork>true</fork>
            </configuration>
        </plugin>
    </plugins>
</build>
3.3.2 Spring-Boot Maven plugin的5个Goals:
  • spring-boot: repackage,默认goal。在mvn package之后,再次打包可执行的jar/war,同时保留mvn package生成的jar/war为.origin
  • spring-boot: run,运行Spring-Boot应用
  • spring-boot: start,在mvn integration-test阶段,进行Spring-Boot应用生命周期的管理
  • spring-boot: stop,在mvn integration-test阶段,进行Spring-Boot应用生命周期的管理
  • spring-boot: build-info,生成Actuator使用的构建信息文件build-info.properties

3.4 application.properties和application.yml

yml: Spring-Boot会加载的配置文件(和properties功能一致,只是文件编辑的格式不同)
除此之外: application.properties 配置中文值的时候,读取出来的属性值会出现乱码问题。但是 application.yml 不会出现乱码问题。原因是,Spring-Boot 是以 iso-8859 的编码方式读取 application.properties 配置文件。
以下是 .properties和 .yml格式对比

3.4.1 application.properties :
  • Spring-Data JPA数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/yourDB
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true

spring.thymeleaf.cache=false
3.4.2 application.yml :
  • Spring-Data JPA数据源配置
spring:
    datasource:
        url: jdbc:mysql://localhost:3306/yourDB
        username: root
        password: root
        driver-class-name: com.mysql.jdbc.Driver
    jpa:
        properties.hibernate.hbm2ddl.auto: update
        properties.hibernate.dialect: org.hibernate.dialect.MySQL5InnoDBDialect
        
        show-sql: true
    thymeleaf:
        cache: false

yml的格式特点:缩进式,"="号使用":"替代,":"之后要使用空格。
yml比properties更能清晰体现结构以及内容,类似eclipse里面的包路径展示方式

3.5 Spring-Boot Application.class

  • Spring-Boot由于内嵌入了Tomcat,在jar项目下,直接开启Application.class就能直接加载配置并开启Tomcat。

@PropertySource 扫描指定路径下的properties

@SpringBootApplication
@PropertySource("classpath:prop/application.properties")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3.6 jasypt-Spring-Boot 配置文件加密

  • 在配置文件.properties或.yml中,数据库连接的账号密码不应该直接暴露。而Spring-Boot与jasypt的整合包可以对我们的配置文件的账号密码进行加密。
@EnableEncryptableProperties
@RunWith(SpringRunner.class)
@SpringBootTest(classes=Deserializers.Base.class)
//@SpringBootTest
public class JaysptTest {
    @Autowired
    private StringEncryptor stringEncryptor;//密码解码器注入

    @Test
    public void test() {
        System.out.println("生成加密后的数据库用户名:"+stringEncryptor.encrypt("root"));
        System.out.println("生成加密后的数据库密码:"+stringEncryptor.encrypt("root"));    
    }
}
  • 得到加密后的信息:
生成加密后的数据库用户名:5KtXuBsNjeQtOuUOR8PPMg==
生成加密后的数据库密码:Y/SEuMVPbIqgimIKqnxFrg==

在配置文件中修改:

  • jasypt.encryptor.password:可以理解为加盐

默认情况下jasypt采用的算法是PBEWithMD5AndDES,该算法对同一串明文每次加密的密文都不一样,比较适合做数据加解密。但是该算法必须配置密码,我们在yml文件配置如下参数

jasypt:
  encryptor:
    password: 123456
  • 加密后的字符串需要放进ENC()里面
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/sbjpa?useUnicode=true&characterEncoding=UTF-8
    username: ENC(5KtXuBsNjeQtOuUOR8PPMg==)
    password: ENC(Y/SEuMVPbIqgimIKqnxFrg==)
    driver-class-name: com.mysql.jdbc.Driver

4 使用Spring-Boot Web项目综合开发

4.1 Spring-Boot 在Controller下的特别注解

  • @RestController 的意思就是controller里面的方法都以json格式输出,不用再进行jackjson、fastjson的配置。
@RestController
public class UsersController {

    @RequestMapping("/users")
    public Map<String, Object> getUsers() {
        Map<String, Object> map = new HashMap<>();
        Users users = new Users();
        users.setUid(001);
        users.setUserName("administrator");
        users.setUserSex("simpleBoy");
        users.setUserAge(16);
        map.put("users", users);
        return map;
    }
}

输出结果为json对象:图片描述

4.2 Spring-Boot下使用Mybatis

相比以往复杂的配置,Spring-Boot的配置相当简单:

    1. 添加相关依赖
<dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.1</version>
</dependency>
4.2.1 无配置文件版使用Mybatis

只用添加相关依赖和application.yml并配合注解即可

  1. 相关的主要依赖(web、mybatis-spring-boot、mysql-connector)
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
        <!--Spring Boot-->
        <!--支持 Web 应用开发,包含 Tomcat 和 spring-mvc -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
        <!--模板引擎-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.1</version>
    </dependency>
    <!--添加适用于生产环境的功能,如性能指标和监测等功能。 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    <-- 这里使用的是MySQL数据库--!>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>
    1. application.yml
mybatis:
    type-aliases-package: com.example.demo.po
    
spring:
    datasource: 
      url: jdbc:mysql://localhost:3306/sbjpa
      username: root
      password: root
      driverClassName: com.mysql.jdbc.Driver
    1. Application.java启动类上加上注解
  • 在启动类中添加对mapper包扫描@MapperScan
  • @MapperScan("com.example.*.dao")扫描多个包下的mapper,可以有以下几种方法扫描
1. @MapperScan("com.example.*.dao")
2. @MapperScan("com.example.test1.dao,com.example.test2.dao")
@SpringBootApplication
@MapperScan("com.example.*.dao")
public class SpringBootMybatisApplication {

    public static void main(String[] args) {
          SpringApplication.run(SpringBootMybatisApplication.class, args);
    }
}
  • Spring-Boot会自动加载spring.datasource.*相关配置,数据源就会自动注入到sqlSessionFactory中,sqlSessionFactory会自动注入到Mapper中,可以直接使用。要么在其他Mapper类上加@Mapper注解,前者更加方便。
public interface UsersMapper {

    @Select("select * from users")
    @Results({ @Result(property = "userName", column = "user_name"), @Result(property = "userSex", column = "user_sex"),
            @Result(property = "userAge", column = "user_age") })
    public List<Users> getAll();

    @Insert("insert into users(user_name,user_sex,user_age) values(#{usersName},#{userSex},#{userAge})")
    public void insert(Users users);

    @Update("update users set user_name=#{usersName},user_sex=#{userSex},user_age=#{userAge}")
    public void update(Users users);

    @Delete("delete from users where uid=#{uid}")
    public void delete(Integer uid);
}

4.2.2 有配置文件XML下的Mybatis使用

  • @MapperScan("com.example.*.dao")扫描多个包下的mapper,可以有以下几种方法扫描
1. @MapperScan("com.example.*.dao")
2. @MapperScan("com.example.test1.dao,com.example.test2.dao")
@SpringBootApplication
@MapperScan("com.example.*.dao")
public class SpringBootMybatisApplication {

    public static void main(String[] args) {
          SpringApplication.run(SpringBootMybatisApplication.class, args);
    }
}
  • 1.application.properties
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.type-aliases-package=com.example.*.po

spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/sbmybatis?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = 
  • 2.UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="com.neo.mapper.UserMapper">
    <resultMap id="BaseResultMap" type="com.neo.entity.UserEntity">
        <id column="id" property="id" jdbcType="BIGINT" />
        <result column="userName" property="userName" jdbcType="VARCHAR" />
        <result column="passWord" property="passWord" jdbcType="VARCHAR" />
        <result column="user_sex" property="userSex" javaType="com.neo.enums.UserSexEnum" />
        <result column="nick_name" property="nickName" jdbcType="VARCHAR" />
    </resultMap>

    <sql id="Base_Column_List">
        id, userName, passWord, user_sex, nick_name
    </sql>

    <sql id="Base_Where_List">
        <if test="userName != null  and userName != ''">
            and userName = #{userName}
        </if>
        <if test="userSex != null and userSex != ''">
            and user_sex = #{userSex}
        </if>
    </sql>

    <select id="getAll" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List" />
        FROM users
    </select>
    
    <select id="getList" resultMap="BaseResultMap" parameterType="com.neo.param.UserParam">
        select
        <include refid="Base_Column_List" />
        from users
        where 1=1
        <include refid="Base_Where_List" />
        order by id desc
        limit #{beginLine} , #{pageSize}
    </select>

    <select id="getCount" resultType="Integer" parameterType="com.neo.param.UserParam">
        select
        count(1)
        from users
        where 1=1
        <include refid="Base_Where_List" />
    </select>

    <select id="getOne" parameterType="Long" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List" />
        FROM users
        WHERE id = #{id}
    </select>

    <insert id="insert" parameterType="com.neo.entity.UserEntity">
        INSERT INTO
        users
        (userName,passWord,user_sex)
        VALUES
        (#{userName}, #{passWord}, #{userSex})
    </insert>

    <update id="update" parameterType="com.neo.entity.UserEntity">
        UPDATE
        users
        SET
        <if test="userName != null">userName = #{userName},</if>
        <if test="passWord != null">passWord = #{passWord},</if>
        nick_name = #{nickName}
        WHERE
        id = #{id}
    </update>

    <delete id="delete" parameterType="Long">
        DELETE FROM
        users
        WHERE
        id =#{id}
    </delete>

</mapper>

RunBird
153 声望3 粉丝

Hello Money