SpringBoot核心技术 之 基础入门

简介: SpringBoot核心技术 之 基础入门

SpringBoot2核心技术 — 基础入门

1、Spring与SpringBoot

1.1、Spring能做什么

1.1.1、Spring的能力

+10.png1.1.2、Spring的生态

https://spring.io/projects/spring-boot


web开发

数据访问

安全控制

分布式

消息服务

移动开发

批处理

1.1.3、Spring5重大升级

① 响应式编程

② 内部源码设计

基于Java8的一些新特性,如:接口默认实现。重新设计源码架构。


1.2、为什么使用SpringBoot

能快速创建出生产级别的Spring应用


1.2.1、SpringBoot的优点

创建独立Spring应用

内嵌web服务器

自动starter依赖,简化构建配置

自动装配Spring以及第三方功能

提供生产级别的监控、健康检查及外部化配置

无代码生产,无需编写XML

SpringBoot是整合Spring技术栈的一站式框架


SpringBoot是简化Spring技术栈的快速开发脚手架


1.2.2、SpringBoot缺点

迭代快,需要时刻关注变化

封装太深,内部原理复杂,不容易精通

1.3、时代背景

1.3.1、微服务

微服务是一种架构风格

一个应用拆分为一组小型服务

每个服务运行在自己的进程内,也就是可以独立部署和升级

服务之间使用轻量级HTTP交互

服务围绕业务功能拆分

可以由全自动部署机制独立部署

去中心化,服务自治。服务可以使用不同的语言、不同的存储技术

1.3.2、分布式

分布式的困难


远程调用

服务发现

负载均衡

服务容错

配置管理

服务监控

链路追踪

日志管理

任务调度

……

分布式的解决


SpringBoot + SpringCloud

+12.png
1.3.3、云原生

原生应用如何上云。Cloud Native


上云的困难


服务自愈

弹性伸缩

服务隔离

自动化部署

灰度发布

流量治理

……

上云的解决


1.4、如何学习SpringBoot

官方文档


查看新版本特性


2、SpringBoot2入门

2.1、系统要求

Java 8 +

Maven 3.5 +

IDEA 2019.1.2

2.2、HelloWorld

2.2.1、创建Maven工程

2.2.2、引入依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.4</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

2.2.3、创建主程序

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

2.2.4、编写业务

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String handle01(){
        return "Hello, SpringBoot!";
    }
}

2.2.5、测试

直接运行main方法

2.2.6、简化配置

application.properties

server.port=8888

2.2.7、简化部署

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

项目打包成 jar 包,直接在目标服务器执行即可。

3、了解自动配置原理

3.1、SpringBoot特点

3.1.1、依赖管理

依赖管理    
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.4</version>
</parent>
他的父项目
 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.7.4</version>
  </parent>
几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制

开发导入starter场景启动器


见到很多 spring-boot-starter-* : *就某种场景

只要引入starter,这个场景的所有常规需要的依赖我们都自动引入

SpringBoot所有支持的场景

https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter

见到的 *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。

所有场景启动器最底层的依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
  <version>2.7.4</version>
  <scope>compile</scope>
</dependency>

无需关注版本号,自动版本号仲裁

引入依赖默认都可以不写版本

引入非版本仲裁的jar,要写版本号

可以修改默认版本号

查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。

在当前 项目里面重写配置

<properties>
    <mysql.version>5.1.43</mysql.version>
</properties>

3.1.2、自动配置

自动配置Tomcat

引入Tomcat依赖

配置Tomcat

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <version>2.7.4</version>
    <scope>compile</scope>
</dependency>

自动配置好SpringMVC


引入SpringMVC全套组件

自动配置好SpringMVC常用组件

自动配置好Web常见功能,如:字符编码问题


SpringBoot帮助我们配置好了所有Web开发常见场景

默认的包结构


主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来


无需以前的包扫描配置


想要改变扫描路径


@SpringBootApplication(scanBasePackages=“com.jignchao”)


或者 @ComponentScan指定扫描路径


@SpringBootApplication 等同于

@SpringBootConfiguration

@EnableAutoConfiguration

@ComponentScan(“com.jingchao.boot”)


各种配置拥有默认值


默认配置最终都是映射到每个类上,如MultipartProperties

配置文件的值最终会绑定到每个类上,这个类会在容器中创建对象

按需加载所有自动配置项


非常多的starter

引入了那些场景这个场景的自动配置才会开启

SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

……


3.2、容器功能

3.2.1、组件添加

① @Configuration

基本使用

Full模式与Lite模式

示例

最佳实战

配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断

配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式

配置类里面使用@Bean标注在方法上面给容器注册组件,默认也是单实例的

配置类本身也是组件

proxyBeanMethods:代理bean的方法

Full(proxyBeanMethods = true)每个@Bean方法调用多少次返回的组件都是单实例的

Lite(proxyBeanMethods = false)每个@Bean方法被调用多少次返回的组件都是新创建的

注意:组件依赖必须使用Full模式(默认),其他情况Lite模式

@Configuration(proxyBeanMethods = false)
public class MyConfig {
    @Bean
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        // user 组件依赖 Pet 组件
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }
    @Bean("tom")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.jingchao.boot")
public class MainApplication {
    public static void main(String[] args) {
        // 返回我们的IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        // 查看容器里面的组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
        // 从容器中获取组件
        Pet tom01 = run.getBean("tom", Pet.class);
        Pet tom02 = run.getBean("tom", Pet.class);
        System.out.println(tom01 == tom02);
        //
        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println(bean);
        User user01 = bean.user01();
        User user02 = bean.user01();
        System.out.println(user02 == user01);
        User user011 = run.getBean("user01", User.class);
        Pet tom = run.getBean("tom", Pet.class);
        System.out.println(user011.getPet() == tom);
    }
}

② @Bean、@Component、@Controller、@Service、@Repository

③ @ComponentScan、@Import

@Import 给容器中自动创建组件,默认组件名字是全类名

@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false)
public class MyConfig(){
}

④ @Conditional

条件装配:满足Conditional指定的条件,则进行组件注入

eg:@ConditionalOnBean

@Configuration(proxyBeanMethods = false)
public class MyConfig {
    @ConditionalOnBean(name = "tom")
    @Bean
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        // user 组件依赖 Pet 组件
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }
    // @Bean("tom")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.jingchao.boot")
public class MainApplication {
    public static void main(String[] args) {
        // 返回我们的IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        // 查看容器里面的组件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
        boolean tom = run.containsBean("tom");
        System.out.println("tom = " + tom);   // false
        boolean user01 = run.containsBean("user01");
        System.out.println("user01 = " + user01); // false
    }
}

3.2.2、原生配置文件引入

① @ImportResource

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean id="j" class="com.jingchao.boot.bean.User">
    <property name="name" value="zhangsan"/>
    <property name="age" value="18"/>
  </bean>
  <bean id="c" class="com.jingchao.boot.bean.Pet">
    <property name="name" value="tomcat"/>
  </bean>
</beans>

直接将 xml 中的组件迁移成注解的方式

@ImportResource("classpath:bean.xml")
public class MyConfig{}
boolean j = run.containsBean("j");
System.out.println(j);        //true
boolean c = run.containsBean("c");
System.out.println(c);        //true

3.2.3、配置绑定

使用 Java 读取到properties文件中的内容,并且把它封装到 JavaBean中哦,以供随时使用

public class getProperties {
     public static void main(String[] args) throws FileNotFoundException, IOException {
         Properties pps = new Properties();
         pps.load(new FileInputStream("a.properties"));
         Enumeration enum1 = pps.propertyNames();//得到配置文件的名字
         while(enum1.hasMoreElements()) {
             String strKey = (String) enum1.nextElement();
             String strValue = pps.getProperty(strKey);
             System.out.println(strKey + "=" + strValue);
             //封装到JavaBean
         }
     }
 }

① @ConfigurationProperties

② @EnableConfigurationProperties + @ConfigurationProperties

@EnableConfigurationProperties(Car.class)
//1、开启Car配置绑定功能
//2、把这个Car这个组件自动注册到容器中
public class MyConfig {
}
@ConfigurationProperties(prefix = "mycar")
public class Car {
    ......
}

③ @Component + @ConfigurationProperties

@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {
    private String brand;
    private Integer price;
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public Integer getPrice() {
        return price;
    }
    public void setPrice(Integer price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}

3.3、自动配置原理入门

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
}

3.3.1、引导加载自动配置类

① @SpringBootConfiguration

@Configuration:代表当前是一个配置类

② @ComponentScan

指定扫描那些组件

③ @EnableConfiguration

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
}

@AutoConfigurationPackage

自动配置包:指定默认的包规则

@Import({AutoConfigurationPackages.Registrar.class})
public @interface AutoConfigurationPackage {
}
/**
* 利用Registrar给容器中导入一系列组件
* 将MainApplication所在包下的所有组件导入进来,  
*/

@Import({AutoConfigurationImportSelector.class})


利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件

调用List configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类

利用工厂加载 Map<String, List> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件

从META-INF/spring.factories位置来加载一个文件。

默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件

spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories

3.3.2、按需开启自动配置项

虽然我们127个场景的所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration

按照条件装配规则(@Conditional),最终会按需配置。


3.3.3、修改默认配置

@Bean
@ConditionalOnBean(MultipartResolver.class)  //容器中有这个类型组件
@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
public MultipartResolver multipartResolver(MultipartResolver resolver) {
    // 给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
    // SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
    // Detect if the user has created a MultipartResolver but named it incorrectly
    return resolver;
}
// 给容器中加入了文件上传解析器;

SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先

@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
}

总结:


SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration


每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定


生效的配置类就会给容器中装配很多组件


只要容器中有这些组件,相当于这些功能就有了


定制化配置


用户直接自己@Bean替换底层的组件

用户去看这个组件是获取的配置文件什么值就去修改。

xxxxxAutoConfiguration --> 组件 --> xxxxProperties里面拿值 --> application.properties


3.3.4、最佳实战

引入场景依赖


https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter

查看自动配置了哪些(选做)


自己分析,引入场景对应的自动配置一般都生效了

配置文件中 debug=true 开启自动配置报告。Negative(不生效)\Positive(生效)

是否需要修改


参照文档修改配置项


https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#common-application-properties

自己分析。xxxxProperties绑定了配置文件的哪些。

自定义加入或者替换组件


@Bean、@Component、……

自定义器 XXXXXCustomizer;



4、开发小技巧

4.1、Lombok

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

简化JavaBean开发

4.2、dev-tools

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>

项目或者页面修改以后:Ctrl+F9

相关文章
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
163 2
|
3月前
|
开发框架 负载均衡 Java
当热门技术负载均衡遇上 Spring Boot,开发者的梦想与挑战在此碰撞,你准备好了吗?
【8月更文挑战第29天】在互联网应用开发中,负载均衡至关重要,可避免单服务器过载导致性能下降或崩溃。Spring Boot 作为流行框架,提供了强大的负载均衡支持,通过合理分配请求至多台服务器,提升系统可用性与可靠性,优化资源利用。本文通过示例展示了如何在 Spring Boot 中配置负载均衡,包括添加依赖、创建负载均衡的 `RestTemplate` 实例及服务接口调用等步骤,帮助开发者构建高效、稳定的应用。随着业务扩展,掌握负载均衡技术将愈发关键。
75 6
|
1月前
|
存储 Java API
简单两步,Spring Boot 写死的定时任务也能动态设置:技术干货分享
【10月更文挑战第4天】在Spring Boot开发中,定时任务通常通过@Scheduled注解来实现,这种方式简单直接,但存在一个显著的限制:任务的执行时间或频率在编译时就已经确定,无法在运行时动态调整。然而,在实际工作中,我们往往需要根据业务需求或外部条件的变化来动态调整定时任务的执行计划。本文将分享一个简单两步的解决方案,让你的Spring Boot应用中的定时任务也能动态设置,从而满足更灵活的业务需求。
84 4
|
1月前
|
存储 JSON 算法
JWT令牌基础教程 全方位带你剖析JWT令牌,在Springboot中使用JWT技术体系,完成拦截器的实现 Interceptor (后附源码)
文章介绍了JWT令牌的基础教程,包括其应用场景、组成部分、生成和校验方法,并在Springboot中使用JWT技术体系完成拦截器的实现。
72 0
JWT令牌基础教程 全方位带你剖析JWT令牌,在Springboot中使用JWT技术体系,完成拦截器的实现 Interceptor (后附源码)
|
2月前
|
存储 缓存 Java
在Spring Boot中使用缓存的技术解析
通过利用Spring Boot中的缓存支持,开发者可以轻松地实现高效和可扩展的缓存策略,进而提升应用的性能和用户体验。Spring Boot的声明式缓存抽象和对多种缓存技术的支持,使得集成和使用缓存变得前所未有的简单。无论是在开发新应用还是优化现有应用,合理地使用缓存都是提高性能的有效手段。
39 1
|
1月前
|
机器学习/深度学习 移动开发 自然语言处理
基于人工智能技术的智能导诊系统源码,SpringBoot作为后端服务的框架,提供快速开发,自动配置和生产级特性
当身体不适却不知该挂哪个科室时,智能导诊系统应运而生。患者只需选择不适部位和症状,系统即可迅速推荐正确科室,避免排错队浪费时间。该系统基于SpringBoot、Redis、MyBatis Plus等技术架构,支持多渠道接入,具备自然语言理解和多输入方式,确保高效精准的导诊体验。无论是线上医疗平台还是大型医院,智能导诊系统均能有效优化就诊流程。
|
3月前
|
缓存 NoSQL Java
SpringBoot的三种缓存技术(Spring Cache、Layering Cache 框架、Alibaba JetCache 框架)
Spring Cache 是 Spring 提供的简易缓存方案,支持本地与 Redis 缓存。通过添加 `spring-boot-starter-data-redis` 和 `spring-boot-starter-cache` 依赖,并使用 `@EnableCaching` 开启缓存功能。JetCache 由阿里开源,功能更丰富,支持多级缓存和异步 API,通过引入 `jetcache-starter-redis` 依赖并配置 YAML 文件启用。Layering Cache 则提供分层缓存机制,需引入 `layering-cache-starter` 依赖并使用特定注解实现缓存逻辑。
971 1
SpringBoot的三种缓存技术(Spring Cache、Layering Cache 框架、Alibaba JetCache 框架)
|
3月前
|
NoSQL JavaScript 前端开发
SpringBoot+Vue实现校园二手系统。前后端分离技术【完整功能介绍+实现详情+源码】
文章介绍了如何使用SpringBoot和Vue实现一个校园二手系统,采用前后端分离技术。系统具备完整的功能,包括客户端和管理员端的界面设计、个人信息管理、商品浏览和交易、订单处理、公告发布等。技术栈包括Vue框架、ElementUI、SpringBoot、Mybatis-plus和Redis。文章还提供了部分源代码,展示了前后端的请求接口和Redis验证码功能实现,以及系统重构和模块化设计的一些思考。
SpringBoot+Vue实现校园二手系统。前后端分离技术【完整功能介绍+实现详情+源码】
|
3月前
|
Java 数据库连接 数据库
告别繁琐 SQL!Hibernate 入门指南带你轻松玩转 ORM,解锁高效数据库操作新姿势
【8月更文挑战第31天】Hibernate 是一款流行的 Java 持久层框架,简化了对象关系映射(ORM)过程,使开发者能以面向对象的方式进行数据持久化操作而无需直接编写 SQL 语句。本文提供 Hibernate 入门指南,介绍核心概念及示例代码,涵盖依赖引入、配置文件设置、实体类定义、工具类构建及基本 CRUD 操作。通过学习,你将掌握使用 Hibernate 简化数据持久化的技巧,为实际项目应用打下基础。
190 0
|
3月前
|
Java 前端开发 Spring
技术融合新潮流!Vaadin携手Spring Boot、React、Angular,引领Web开发变革,你准备好了吗?
【8月更文挑战第31天】本文探讨了Vaadin与Spring Boot、React及Angular等主流技术栈的最佳融合实践。Vaadin作为现代Java Web框架,与其他技术栈结合能更好地满足复杂应用需求。文中通过示例代码展示了如何在Spring Boot项目中集成Vaadin,以及如何在Vaadin项目中使用React和Angular组件,充分发挥各技术栈的优势,提升开发效率和用户体验。开发者可根据具体需求选择合适的技术组合。
73 0