Java essay Java essay
首页
  • Java基础
  • Java进阶
  • 设计模式
  • 多线程
  • Java你不知道的小事
  • Spring初识
  • Spring进阶
  • SpringBoot基础
  • SpringBoot进阶
  • 什么是微服务
  • SpringCloud全家桶
  • Dubbo
  • SpringCloud Alibaba
  • Vue
  • 小程序
  • 博客搭建
  • 数据库
  • python
  • 大数据
  • 性能分析优化
  • 中间件
  • 云原生
  • 面试
  • 外卖霸王餐
  • 打工人的带饭生活
  • 30岁我该怎么办
友链
关于我
GitHub (opens new window)

Mr.Fire

全栈工程师
首页
  • Java基础
  • Java进阶
  • 设计模式
  • 多线程
  • Java你不知道的小事
  • Spring初识
  • Spring进阶
  • SpringBoot基础
  • SpringBoot进阶
  • 什么是微服务
  • SpringCloud全家桶
  • Dubbo
  • SpringCloud Alibaba
  • Vue
  • 小程序
  • 博客搭建
  • 数据库
  • python
  • 大数据
  • 性能分析优化
  • 中间件
  • 云原生
  • 面试
  • 外卖霸王餐
  • 打工人的带饭生活
  • 30岁我该怎么办
友链
关于我
GitHub (opens new window)
  • Spring

  • Spring进阶

  • SpringBoot基础

    • SpringBoot初识
    • SpringBoot基础
      • 1 基础
        • 1.1 Springboot介绍
        • 1.1.1 回顾以前的SSM,SSH项目
        • 1.1.2 Sping的优缺点分析
        • 1.1.3 什么是SpringBoot
        • 1.2 约定优于配置
        • 1.3 快速上手SpringBoot
        • 1.4 配置文件和注解配置
        • 1.4.1 SpringBoot配置文件的加载顺序
        • 1.4.2 常用属性
        • 1.4.2 application.propertites和application.yml共存
        • 1.4.3 拆分多环境配置
        • 1.4.4 多配置文件加载问题
        • 1.4.5 常用条件注解
        • 1.5 AOP处理
        • 1.5.1 什么是AOP
        • 1.5.2 Aop术语
        • 1.5.3常用的Aop增强类型
        • 1.5.4 实战
        • 1.6 单元测试和热部署
      • 1.7 打包部署
      • 2 进阶
        • 2.1 SpringBoot启动流程及自动装配及原理
        • 2.2 Starter组件及命名规范
        • 2.3 SpingBoot整合Spring Data JPA
    • SpringBoot集成MyBatis
    • SpringBoot自定义Starter
    • SpingBoot常用工具类
  • SpringBoot进阶

  • Spring
  • SpringBoot基础
Mr.Fire
2022-06-28
目录

SpringBoot基础

  • 1 基础
    • 1.1 Springboot介绍
    • 1.2 约定优于配置
    • 1.3 快速上手SpringBoot
    • 1.4 配置文件和注解配置
    • 1.5 AOP处理
    • 1.6 单元测试和热部署
  • 1.7 打包部署
  • 2 进阶
    • 2.1 SpringBoot启动流程及自动装配及原理
    • 2.2 Starter组件及命名规范
    • 2.3 SpingBoot整合Spring Data JPA

# 1 基础

# 1.1 Springboot介绍

# 1.1.1 回顾以前的SSM,SSH项目

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

# 1.1.2 Sping的优缺点分析

优点: Spring是java企业级(J2EE)的轻量级代替品,为企业级开发提供了一种相对简单的方法,通过一来入驻和面向切面编程,用简单的java对象实现了EJB的功能。

缺点: 虽然Spring是轻量级的,但它的配置是重量级的。一开始,Spring用XML配置,而且很多XML配置,Spring2.5引入了基于注解的组件扫描,消除了大量针对应用程序自身组件的显示XML配置。 Spring3.0开始引入了基于java的配置,这是一种类型安全的可重构配置方式,可以替代XML。所有这些配置都代表了开发时的损耗,挤占了编写程序逻辑的时间。 除此之外,项目依赖管理也是一件损时耗力的事情,需要分析要导入哪些依赖。依赖之间的关系,版本之间不兼容等问题

# 1.1.3 什么是SpringBoot

从本质上来说,springboot是一个专注于框架的框架。Spring Boot就是对各种框架的整合,让他们集成在一起更加简单,简化了我们在集成过程中的模板化配置, 它做了那些没有它你自己也会去做的Spring Bean配置。你不用再写这些样板配置了,可以专注于应用程序的逻辑,这些才是应用程序独一无二的东西。

SpringBoot对Spring的缺点进行改善和优化,基于约定优于配置的思想,开发人员不必在配置与逻辑业务之间进行思维的切换,专注于业务逻辑的开发,提高开发效率。

起步依赖

本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起支持某项功能。简单的说,就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。

自动配置

指的是Springboot会自动将一些配置类的bean注册到IOC容器中,我们可以在需要的地方使用@Autowired或者@Resource等注解来使用它。 “自动”的表现形式就是我们只需要引入我们要用的功能的包,相关的陪着我们完全不用管,SpringBoot会自动注入这些配置bean,我们直接使用这些bean即可。

SpringBoot的简单、快速、方便的搭建项目,对主流开发框架的无配置集成,极大提高开发,部署效率。

# 1.2 约定优于配置

这是形容springBoot最常用的描述,也有人解读为:约定大于配置,约定好于配置,习惯大于配置等。

用springBoot框架开发程序时,框架提供的默认值会让我们的项目开发起来效率更快,如果默认值满足不了我们的需求,我们可以使用Properties配置文件和YAML配置文件来重写默认值来满足我们的需求,所以约定大于配置,是说通过约定来较少配置,从而提升开发效率。

而且约定大于配置,并不是一种新的思想,在JDK5.0发布,采用元数据 ,引入注解的概念(也称之为标注),就代表简化配置的开始,就是初期的一种 “约定优于配置” 的体现;所以约定优于配置这一设计理念,从 Spring 的注解版本就已经开始了。引入注解就是为了减少一些默认配置,引入注解也就代表着简化配置的开始,官方说基于 spring 的基础就是这个事实。

# 1.3 快速上手SpringBoot

# 1.4 配置文件和注解配置

# 1.4.1 SpringBoot配置文件的加载顺序

  • 工程根目录:./config/
  • 工程根目录:./
  • classpath:/config/
  • classpath:/

优先级顺序是从上向下加载,所有的文件都会被加载,高优先级的内容会覆盖低优先级的内容,形成互补配置

# 1.4.2 常用属性

  1. --spring.config.name: 修改配置文件前缀
  2. --spring.config.location:定制路径,加载配置文件
  3. --spring.profiles.active :可以使用不同profile来区分环境。格式:application-{profile}.properties
  4. --spring.profiles.include :,引入其他配置文件,包含

# 1.4.2 application.propertites和application.yml共存

当application.properties和yml文件在并存时(同一目录下),application.properties优先级更好,会先读它,若它没有,再去读yml中的值。

# 1.4.3 拆分多环境配置

通过---可以把一个yml文档分割为多个或者创建 application-{profile}.properties/yml

# 1.4.4 多配置文件加载问题

使用spring.profile.include引入其他配置文件,可propertites和yml混合使用,也可单独使用

(1)application.propertites格式问题

a.前后空格、等号左右空格是否有影响? 无影响

b.换行是否报错? key换行不能正常读取属性值不报错,值换行正常读取(除带特殊符号的)

c.指定include中的文件不存在是否报错? 不报错

d.命名得是application-profile的形式,eg:application-test.properties

(2)加载顺序问题

spring.profiles.include属性配置顺序为主,后加载的会覆盖前面的 如:spring.profiles.include =redis,sys,sql,dev redis和sql中同時配置了端口号,最后使用的是sql配置文件中的值

(3)外部配置文件 外部的配置文件优先加载 加载顺序也是按include属性中配置的顺序加载, 如果有相同的属性,外部配置文件会覆盖内部文件属性。

命令参考: a)jar、war包和配置文件不在同级目录下

java -jar demo.war-1.0.0-SNAPSHOT.war
--spring.config.location=C:\Users\lumingfu\Desktop\test\protest\application-mysql.properties,C:\Users\lumingfu\Desktop\test\protest\application.yml

1
2
3

或者

java -jar demo.war-1.0.0-SNAPSHOT.war
--spring.config.location=C:\Users\lumingfu\Desktop\test\protest\  
1
2

或者

#加载内部的yml
--spring.config.location=classpath:/config/application.yml,C:\Users\lumingfu\Desktop\test\application-mysql.properties
1
2

b)jar,war包和配置文件在同级目录下或者同级/config目录下 可加载到内部配置文件,如需要引入外部配置文件,可不写或者用--spring.profiles.active 或--spring.profiles.include引入

# 1.4.5 常用条件注解

我们可以通过debug=true來打印自动配置报告,可以很方便的知道哪些自动配置生效

# 1.5 AOP处理

# 1.5.1 什么是AOP

面向切面编程,相对于OOP面向对象编程,Spring的AOP的存在目的是为了解耦。AOP可以让一组类共享相同的行为。 在OOP中只能继承和实现接口,且类继承只能单继承,阻碍更多行为添加到一组类上,AOP弥补了OOP的不足。还有就是为了清晰的逻辑,让业务逻辑关注业务本身, 不用去关心其它的事情,比如事务。Spring的AOP是通过JDK的动态代理和CGLIB实现的。

# 1.5.2 Aop术语

aop 有一堆术语,非常难以理解,简单说一下

  • 通知(有的地方叫增强)(Advice): 需要完成的工作叫做通知,就是你写的业务逻辑中需要比如事务、日志等先定义好,然后需要的地方再去用

  • 连接点(Join point): 就是spring中允许使用通知的地方,基本上每个方法前后抛异常时都可以是连接点

  • 切点(Poincut): 其实就是筛选出的连接点,一个类中的所有方法都是连接点,但又不全需要,会筛选出某些作为连接点做为切点。如果说通知定义了切面的动作或者执行时机的话,切点则定义了执行的地点

  • 切面(Aspect): 其实就是通知和切点的结合,通知和切点共同定义了切面的全部内容,它是干什么的,什么时候在哪执行

  • 引入(Introduction): 在不改变一个现有类代码的情况下,为该类添加属性和方法,可以在无需修改现有类的前提下,让它们具有新的行为和状态。其实就是把切面(也就是新方法属性:通知定义的)用到目标类中去

  • 目标(target): 被通知的对象。也就是需要加入额外代码的对象,也就是真正的业务逻辑被组织织入切面。

  • 织入(Weaving): 把切面加入程序代码的过程。切面在指定的连接点被织入到目标对象中,在目标对象的生命周期里有多个点可以进行织入:

    1. 编译期: 切面在目标类编译时被织入,这种方式需要特殊的编译器

    2. 类加载期: 切面在目标类加载到JVM时被织入,这种方式需要特殊的类加载器,它可以在目标类被引入应用之前增强该目标类的字节码

    3. 运行期: 切面在应用运行的某个时刻被织入,一般情况下,在织入切面时,AOP容器会为目标对象动态创建一个代理对象,Spring AOP就是以这种方式织入切面的。

# 1.5.3常用的Aop增强类型

before(前置通知): 在方法开始执行前执行 after(后置通知): 在方法执行后执行 afterReturning(返回后通知): 在方法返回后执行 afterThrowing(异常通知): 在抛出异常时执行 around(环绕通知): 在方法执行前和执行后都会执行

执行顺序:around > before > around > after > afterReturning

# 1.5.4 实战

(1)引入依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
  <version>2.5.5</version>
</dependency>
1
2
3
4
5

(2)切面类

/**
* @author Mr.Fire -lmf
* @desc Aop切面类
*
* Spring AOP常用于拦截器、事务、日志、权限验证等方面
  */
  @Aspect
  @Component
  public class AopAspect {

    @Pointcut("execution(* com.springboot.demo.web.TestContoller.query())")
    public void pointQuery(){
    }
  
    @Pointcut("execution(* com.springboot.demo.dao.UserJpaRepository.queyNameLike(..))")
    public void pointQueryByName(){
    }


    /**
     * 目标方法执行之前
     */
    @After(value = "pointQuery()")
    public void after(){
        System.out.println("after query point processed");
    }

    /**
     * 目标方法执行之后
     */
    @Before(value = "pointQuery()")
    public void before(){
        System.out.println("before query point processed");
    }

    /**
     * @Around的作用
     *
     * 既可以在目标方法之前织入增强动作,也可以在执行目标方法之后织入增强动作;
     * 可以决定目标方法在什么时候执行,如何执行,甚至可以完全阻止目标目标方法的执行;
     * 可以改变执行目标方法的参数值,也可以改变执行目标方法之后的返回值; 当需要改变目标方法的返回值时,只能使用Around方法;
     */
    @Around(value = "pointQuery()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println("around query point processed");
        try {
            //果调用joinPoint.proceed()方法,则修改的参数值不会生效,必须调用joinPoint.proceed(Object[] args)
            Object result = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
            //如果这里不返回result,则目标对象实际返回值会被置为null
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }

    /**
     * 目标方法返回之后执行
     * @param user
     */
    @AfterReturning(value = "pointQuery()",returning = "user")
    public void afterQueryToDo(Object user){
        System.out.println("afterReturning query point processed");
        System.out.println("执行结果:"+user.toString());
    }

    @AfterReturning(value = "pointQueryByName()",returning = "user")
    public void afterQueryToDo(JoinPoint joinPoint,Object user){
        System.out.println("参数:"+joinPoint.getArgs()[0]);
        System.out.println("执行结果:"+user.toString());
    }

    /**
     * 目标方法抛异常之后执行
     * @param ex
     */
    @AfterThrowing(value = "pointQueryByName()",throwing = "ex")
    public void afterThrows(Throwable ex){
        System.out.println(ex.getCause());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

# 1.6 单元测试和热部署

(1)引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional><!--依赖不会进行传递-->
</dependency>
1
2
3
4
5
6
7
8
9
10

(2)热部署需要配置自动编译 快捷键ctrl + alt + shift + / 选择Register 勾选下面两个

(3)测试用例 编写测试用例类

@SpringBootTest  //标记为SpringBoot单元测试类,并加载项目的上下文环境
class BootDemoApplicationTests {

    @Autowired
    TestContoller testContoller;

    @Autowired
    UserJpaRepository userJpaRepository;

    @Test
    void query() {
        User user = testContoller.query();
        System.out.println(user.toString());
        System.out.println("hello word");
    }

    @Test
    void queryAll() {
        List<User> users = testContoller.queryList();
        users.forEach(user -> System.out.println(user.toString()));
        System.out.println("hello word");
    }

    @Test
    void queryByLike(){
        List<User> users = userJpaRepository.queyNameLike("cc");
        users.forEach(user -> System.out.println(user.toString()));

    }

    @Test
    void update(){
        userJpaRepository.updatePwdName("123456","cc");
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# 1.7 打包部署

(1)引入插件

<plugins>
  <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
  </plugin>
</plugins>
1
2
3
4
5
6

(2)pom文件中定义打包类型

<packaging>jar</packaging>
1

(3)运行

jar包:

java -jar boot-demo.jar
1

war包:中间件部署

# 2 进阶

# 2.1 SpringBoot启动流程及自动装配及原理

默认启动类在最包的上层,否则在启动类之上的不会自动扫描到

# 2.2 Starter组件及命名规范

Starter是什么?

Starter 是SpringBoot四大组件之一,是一组惯例依赖描述资源,可以包含在应用中。从 starter 中,您可以获得所需的所有 Spring 和相关技术的一站式支持,无须通过示例代码和复制粘贴来获取依赖。比如,如果您要使用 Spring 和 JPA 进行数据库访问,那么只需要在项目中包含 spring-boot-starter-data-jpa 依赖项即可。 starter 包含了许多您需要用于使项目快速启动和运行,并且需要一组受支持的可传递依赖关系的依赖。


命名含义

官方的所有 starter 都遵循类似的命名规则:spring-boot-starter-*,其中 * 是特定类型的应用。这个命名结构旨在帮助您找到 starter。 许多 IDE 中 Maven 集成允许您按名称搜索依赖。例如,安装了 Eclipse 或者 STS 插件后,您可以简单地在 POM 编辑器中按下 ctrl-space 并输入 spring-boot-starter 来获取完整的列表。 第三方的 starter 命名不应该以 spring-boot 开头,因为它是官方 Spring Boot 构件所保留的规则。例如,有一个第三方 starter 项目叫做 thirdpartyproject, 它通常会命名为 thirdpartyproject-spring-boot-starter。

SpringBoot自动装配原理移步:https://javaessay.cn/pages/7fb4a5/ (opens new window)

# 2.3 SpingBoot整合Spring Data JPA

(1)引入依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
1
2
3
4

(2)编写Repoistory接口

/**
* @author Mr.Fire -lmf
* @date 2021/10/9 15:39
* @desc Jpa接口
* <p>Repository接口 ,提供了方法名称命名查询方式,findBy</p>
* <p>JpaRepository接口,基于@Query注解查询与更新</p>
* <p>CrudRepository接口,主要是完成一些增删改查的操作。注意:CrudRepository接口继承了Repository接口</p>
* <p>JpaSpecificationExecutor接口,自定义多条件查询</p>
*
*/
public interface UserJpaRepository extends Repository<User,Integer>,
JpaRepository<User,Integer>,
CrudRepository<User,Integer>,
PagingAndSortingRepository<User,Integer>,
JpaSpecificationExecutor<User> {


    /**
     *
     * @param name
     * @return
     */
    User findByUserName(String name);

    /**
     *
     * @return
     */
    @Query(value = "from User where userName = ?1")
    User queryByNameHQL(String name);

    /**
     * 查询
     * @return
     */
    @Query(value = "select *from user where user_name like ?1%",nativeQuery = true)
    List<User> queyNameLike(String name);

    /**
     * 修改
     * @param password
     * @param userName
     */
    @Query(value = "update user set password = :password where user_name = :userName ",nativeQuery = true)
    @Modifying
    void updatePwdName(@Param("password") String password, @Param("userName") String userName);

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

(3)调用接口

@RestController
@RequestMapping("/test")
public class TestContoller {

    @Autowired
    UserJpaRepository jpaRepository;

    @Autowired
    ChildrenService childrenService;

    @GetMapping("/hello")
    public String helloWorld(){
        return "Hello SpringBoot!!!";
    }

    @RequestMapping(value = "/query",method = RequestMethod.GET)
    public User query(){
        return jpaRepository.findByUserName("cc");
    }

    @RequestMapping(value = "/queryList",method = RequestMethod.GET)
    public List<User> queryList(){
        return jpaRepository.findAll();
    }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#SpringBoot
最后更新时间: 2024/03/15, 17:35:22
SpringBoot初识
SpringBoot集成MyBatis

← SpringBoot初识 SpringBoot集成MyBatis→

最近更新
01
SuperBuilder
12-29
02
30岁我该怎么办
12-29
03
关于存钱
12-29
更多文章>
Theme by Vdoing | Copyright © 2021-2025 Mr.Fire | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式