【SpringBoot】一、SpringBoot概述以及其自动配置基本原理

news/2025/2/19 7:32:54/

SpringBoot

SpringBoot现在分为两个技术栈,第一个是常规的使用servletAPI的Web编程方式,第二种是使用Reactive方式的响应式编程,Reactive Stack可以使用很少的内存来实现复杂的功能,提升性能并压缩成本,是一种很好的新型方式

SpringBoot优点

  • 创建一个完整的、独立的Spring应用
  • 内嵌独立的Tomcat服务器,不需要再进行其他配置
  • 自动处理依赖关系,不需要自己进行依赖管理
  • 自动配置spring以及第三方功能
  • 自动进行生产级别的健康监控
  • 无代码生成,不会因为一次一次的运行添加过多的代码

SpringBoot特点就是使用微服务构建出一个个的独立的模块,再用这些独立出来的模块进行分布式开发,分布式所涉及的问题可以由Spring Cloud进行解决,而产生的数据流也可以使用Spring Cloud Data Flow处理

使用SpringBoot的一个Demo

  • 需要先创建一个maven项目并在项目的pom.xml文件中声明父工程:

在pom.xml文件中:

需要联网并下载依赖文件

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version></parent>
  • 只需要导入web场景启动器依赖就可以,不用其他复杂依赖

    这个依赖中包括日志、springmvc等所有需要的依赖

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
  • 进行主类启动器的编写:
/*** @SpringBootApplication注解* 用来标识这是一个SpringBoot应用* 这个类是一个固定写法,作为springboot启动器*/
@SpringBootApplication
public class MainApplication {//固定写法public static void main(String[] args) {//参数为这个类的Class对象SpringApplication.run(MainApplication.class);}
}
  • 进行Controller层的编写
/*** @ResponseBody注解用于标识所有的Return值是写给浏览器的,而不是代表跳转*/
//@ResponseBody
//@Controller/*** @RestController注解代表@Controller注解与@ResponseBody注解的合体* 是需要同时用到两个注解时的简单写法*/
@RestController
public class HelloController {@RequestMapping("/Hello")public String handle01() {return "Hello SpringBoot2!";}
}

所有的SpringBoot的配置都集成在application.properties文件中

例如端口号的修改只需要在Application.properties中添加server.port=新端口号即可

server.port=8888

另外,在简化pom.xml文件中加入构建项目的依赖:

<!--    这个构建加入之后,进行打包就可以在cmd环境下直接运行springboot的项目,tomcat被直接集成在项目中--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

这样在cmd的 java -jar命令下就可以直接在cmd的环境下运行这个项目

注意:在springboot环境下,所有的项目都是由父工程springboot进行统一管理的。

若需要某些依赖固定一些版本的话,则需要在pom.xml文件中添加properties标签并加入对应依赖属性,例如mysql版本的改变

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

记得在springboot依赖中找到对应的依赖的key属性

springboot是基于主程序所在的包进行包扫描的,所有与主程序在同一个包下的注解都会被扫描,但也可以进行扩大,只要在@SpringBootApplication的scanBasePackages属性下声明好就可以将扫描的包路径扩大。

SpringBoot的自动配置也是按需加载的,不会把所有的配置都加载,而是会在配置了对应的启动配置之后才会生效。

SpringBoot的配置文件

@Configuration注解用来标识一个类为配置类,Spring会寻找这个注解并将这个注解下的类中的方法视作创建对象,例如IoC中,对于对象的依赖注入就可以下面这么写:

在boot文件夹下创建配置类的存放文件夹config并创建一个类:MyConfig.java

//@Configuration注解,用来标识一个类,作用是进行配置,让SpringBoot来进行扫描时以配置类的眼光来看这个类以及其下的方法
@Configuration
public class MyConfig {@Bean       //进行注入的注解,标识一个方法表示这个方法的返回值作为要返回的对象,返回值类型作为要创建的对象类型,方法名作为对象的id属性public User user01() {return new User("ZhangGeGe", 18);}//或者在Bean注解中添加一个value,则组件名后面就叫这个value的属性值,不会再叫方法名了。@Bean("Tom")public Pet cat() {return new Pet("Tomcat");}
}

验证配置:

在主类中通过循环获取所有的组件名称后可以看到有user01和Tom出现

    public static void main(String[] args) {//参数为这个类的Class对象ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class);//查看容器内组件String[] names = run.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}

并且是通过单例模式进行创建,因此会相等:

        //查看容器内组件String[] names = run.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}Pet tom = run.getBean("Tom", Pet.class);Pet tom1 = run.getBean("Tom", Pet.class);System.out.println("组件:" + (tom == tom1));

此外:@Configuration还有一个proxyBeanMethods属性:

该属性:

//proxyBeanMethods属性代表其是否使用代理,使用代理则其为单例模式,每一个类只有一个对象,false则在每次调用的时候都会新创建一个对象
@Configuration(proxyBeanMethods = true)
        //从容器中获取对象User user = bean.user01();User user1 = bean.user01();System.out.println("是否是一个:" + (user == user1));

简而言之:

  • 不需要组件之间有依赖关系,允许多个实例时使用Lite模式(proxyBeanMethods = false),关闭它就不会检查容器中是否已有
  • 需要依赖关系时使用Full模式(proxyBeanMethods = true)

@Import

@Import注解用于标注组件,并向容器中注入对象,这种方式注入的对象组件名叫做全类名,且会与@Bean注解注入的方式注入不同的对象,也就是说在容器中会存在两个组件

//Import组件,其形参是一个Class型的数据,只要在其中声明了,就会在容器中创建对应的对象
@Import({User.class, DBHelper.class})

@Conditional

Conditional组件用来标注类或者方法,只有当Conditional组件中内容成立时才会执行其所标注的语句

例如ConditionalOnBean注解标注时,只有当容器中有某个组件,下面语句才生效

@ConditionalOnBean(name = "Tom")

再录入@ConditionalOnMissingBean就代表容器中没有某个组件时才令下面的语句生效

@ImportResource

若有之前的第三方插件使用配置文件的方式进行文件配置时,可以在Config类上添加@ImportResource注解来将配置文件中的对象注入到容器中。

@ImportResource("classpath:bean.xml")

之后在容器中进行操作时就可以使用run.getBean(String)方法来获取组件。

@ConfigurationProperties 配置绑定

SpringBoot还提供了在配置文件中进行容器中组件的属性配置功能,在配置文件中以xxx.属性的方式进行配置,并在类上标识@ConfigurationProperties注解以及@Component注解来保证其存在于容器中,就可以进行属性配置,例如:

Application.proprties:

mycar.brand=BYD
mycar.price=100000

要绑定的类:

@Component
//.前面的要相等
@ConfigurationProperties(prefix = "mycar")
public class Car {private String brand;private Integer price;

另外,也可以使用@EnableConfigurationProperties注解来将指定的类来注入容器中,这个注解可以视作在Car类上标注了@Component注解,将这个类的对象组件直接加入容器。

@EnableConfigurationProperties(Car.class)

注意就算用了Enable这个注解,@ConfigurationProperties(prefix = “mycar”)这个注解也还是要写。

源码解析

@SpringBootApplication注解:

该注解相当于三个注解合起来:

@SpringBootConfiguration

@EnableAutoConfiguration

@ComponentScan(“要扫描的包名”)

  • @SpringBootConfiguration底层中是一个@Configuration注解,标注Main类也是一个配置类的组件,主要作用是将其标注为启动类
  • @ComponentScan(“要扫描的包名”)指定要扫描的包的路径,指明哪些包需要扫描
  • @EnableAutoConfiguration中又是由@AutoConfigurationPackage组成的,这个注解标注了组件的注册,注册的地址是Main类所在的路径,故而我们的组件是从Main所在的文件夹决定的。

另外,@EnableAutoConfiguration注解也由@Import注解组成,该注解决定了SpringBoot在启动时加载所有的自动配置类,但只有在对应的配置需要开启时(有对应的组件导入时)才开启。(默认全部开启装载,但按需配置)

若使用@Bean注解的方法有形参传入,则传入的形参会自动从容器中找

关于配置与Application.Properties的绑定

所有的配置都会有一个xxxxAutoConfiguration类,这个类都会有一个@EnableConfigurationProperties注解,这个注解决定了自动配置需要的类,而这个类上一般会有@ConfigurationProperties注解,这个注解的prefix属性就决定了我们要在Application.properties文件中配置的属性的开头是哪些


http://www.ppmy.cn/news/101947.html

相关文章

武汉研究所分享

中船重工旗下有六个研究所&#xff0c;分别为701、719、712、722、717、709。此外&#xff0c;中国航天三江集团有限公司也是不错的选择。以下是各所简要介绍&#xff1a; 701所&#xff1a;总体所&#xff0c;专攻舰船设计&#xff0c;招收专业方向广泛。以船舶、机械、电力、…

js中async与await详解

引言 JavaScript 是一门基于事件驱动和异步编程的语言&#xff0c;而异步编程是 JavaScript 中最常用的编程方式之一。在异步编程中&#xff0c;我们通常使用回调函数或 Promise 对象来处理异步操作的结果。而在 ES2017 中&#xff0c;引入了 async 和 await 关键字&#xff0c…

G0第24章:GORM CRUD指南 、 Hook介绍

07 CRUD CRUD通常指数据库的增删改查操作&#xff0c;本文详细介绍了如何使用GORM实现创建、查询、更新和删除操作。 本文中的db变量为*gorm.DB对象&#xff0c;例如&#xff1a; import ("gorm.io/driver/mysql""gorm.io/gorm" )func main() {// 参考 …

Swift 中的 Actors 使用以及如何防止数据竞争

文章目录 前言Actors 的基本原理Actor 是引用类型&#xff0c;但与类相比仍然有所不同 为什么会出现数据竞争如何防止数据竞争使用 async/await 访问数据防止不必要的暂停非隔离(nonisolated)访问为什么在使用 Actors 时仍会出现数据竞争&#xff1f;总结 前言 Actors 是 Swif…

渲大师云主机按量付费功能上线!

云主机可以提供强大的计算和存储能力&#xff0c;通过使用云主机&#xff0c;政企办公、视觉设计、影视制作和深度学习领域的专业人士可以获得更大的灵活性、可扩展性和计算能力&#xff0c;提高工作效率和效果。 然而&#xff0c;当我们在选择和使用云主机时&#xff0c;需要…

SpringMvc源码分析

概述 用户的请求&#xff0c;是如何被 DispatcherServlet 处理的 先看图 从图中可以看到请求首先是被 DispatcherServlet 所处理&#xff0c;但是实际上&#xff0c;FrameworkServlet 先被触发 我们看下处理各种请求的方法 Overrideprotected final void doGet(HttpServletR…

可数集和不可数集

有限集和无限集 后继集 设 S S S是任一集合&#xff0c;称 S S ∪ { S } S^ S\cup \left\{ S\right\} SS∪{S}为 S S S的后继集 自然数集 自然数集 N \mathbb{N} N的归纳定义是&#xff1a; &#xff08;1&#xff09; ∅ ∈ N \empty \in \mathbb{N} ∅∈N &#xff08…

Oracle 表空间文件迁移(亲测)

背景&#xff1a;由于各种原因&#xff0c;在实际工作中可能会出现oracle服务器数据盘空间被占满的情况&#xff0c;这个时候单纯的添加新磁盘&#xff0c;后续表空间文件放新盘的方案已经不适用了&#xff0c;因为源盘已经占用满了&#xff0c;数据库服务会异常&#xff0c;且…