一、SpringBoot入门
1.1 什么是SpringBoot
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
官网这个图我们来简单了解一下,可以通过SpringBoot快速构建一个一个小的模块,我们可以认为是开发出一个个的微服务
之后通过SpringCloud协调你开发的微服务模块,这些微服务可以通过springdata进行数据交互
学习SpringBoot之前应该先学习SSM框架之后再来学习,这样才能体会到它带来的便利!
1.2 SpringBoot优缺点
优点:
创建独立Spring应用
内嵌web服务器
自动starter依赖,简化构建配置
自动配置Spring以及第三方功能
提供生产级别的监控、健康检查及外部化配置
无代码生成、无需编写XML
SpringBoot是整合Spring技术栈的一站式框架
SpringBoot是简化Spring技术栈的快速开发脚手架
什么是脚手架???
对于程序员来说脚手架就是代码生成器。不用重复的进行创建类和基本的增删改查等工作。只需要按照步骤配置好,就能自动完成基础类和各个实现类等的创建了。
缺点:
更新快,需要不断学习新技术
封装太深,不利于精通
1.3 SpringBoot快速入门
环境如下:
1.3.1 通过Maven导入依赖
pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.caq</groupId> <artifactId>SpringBootStudy</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
在SpringBoot中我们想进行WEB开发,可以直接导入一个spring-boot-starter-web即可
在原来的SSM阶段我们要导入大量的包,springboot中这一个包就可以把SSM阶段WEB开发需要的都导入进来
1.3.2 直接上代码运行
主程序代码
@SpringBootApplication代表这是一个springboot应用 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);属于固定写法 package com.caq.boot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class MainApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); } }
控制层代码
@RestController是@ResponseBody的结合@Controller @Controller是创建 @RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。 package com.caq.boot.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class Controller { @RequestMapping("/hello") public String handle01(){ return "Hello SpringBoot 2 !"; } }
运行主程序访问8080端口
测试成功~~
1.4 简化配置
写一个application.properties配置文件,所有的配置文件都可以写这里面
比如我们改tomcat的端口号为8089
如下所示:
server.port=8089
重新启动程序访问测试
1.5 简化部署
把项目打成jar包,直接在目标服务器执行即可。
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
通过如下命令运行我们的程序
java -jar 运行我们的jar包
dir查看当前目录下的文件
测试依旧可以访问,我还更改了返回的字符串
二、了解自动配置原理
2.1 SpringBoot特点
2.1.1 依赖管理
父项目是用来解决依赖管理的
标签是maven中的继承,是用来做依赖管理的
spring-boot-dependencies是spring-boot-starter-parent的父项目。它几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制
spring-boot-starter-* : *就某种场景
只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> </parent> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.3.4.RELEASE</version> </parent>
修改默认版本号
在pom里直接写 这个标签,写你想要的版本即可
1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
2、在当前项目里面重写配置
<properties> <mysql.version>5.1.43</mysql.version> </properties>
2.1.2 自动配置
自动配好SpringMVC
引入SpringMVC全套组件
自动配好SpringMVC常用组件(功能)
自动配好Web常见功能,如:字符编码问题
SpringBoot帮我们配置好了所有web开发的常见场景
默认的包结构
主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
无需以前的包扫描配置
想要改变扫描路径,@SpringBootApplication(scanBasePackages=“com.example”)
@SpringBootApplication
等同于
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan("com.caq.boot")
@EnableAutoConfiguration帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot,并创建对应配置类的Bean,并把该Bean实体交给IoC容器进行管理。
各种配置拥有默认值
默认配置最终都是映射到某个类上,如:MultipartProperties
配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
按需加载所有自动配置项
非常多的starter
引入了哪些场景这个场景的自动配置才会开启
SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面
那么它是如何自动配置的呢?
我们需要先了解下SpringBoot底层的相关注解
2.2 常见注解
2.2.1 @Bean
==@Bean给容器中添加组件。==以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
组件的概念在上面提到了就是符合某种规范的类,可以理解为给容器中添加对象
/** User类和Pet要提前写好 */ @Bean public User user01(){ return new User("zs",12); } 这个我们自定义一个名字,不用方法名作为实例的名字了 @Bean("tiger") public Pet animal01(){ return new Pet("li"); }
如下,SpringApplication.run()返回值是把IOC容器返回给我们了
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
1
我们用返回的IOC容器进行测试看看通过@Bean添加的组件有没有添加成功
@SpringBootApplication public class MainApplication { public static void main(String[] args) { // 1.返回值是IOC容器 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); boolean tiger1 = run.containsBean("tiger"); System.out.println(tiger1); boolean user01 = run.containsBean("user01"); System.out.println(user01); } }
2.2.2 @Configuration
组件(component):
组件也是抽象的概念,可以理解为一些符合某种规范的类组合在一起就构成了组件。他可以提供某些特定的功能。J2EE来说,有什么servlet,jsp, javabean,ejb都是组件。但实际他们都是类,只不过有他们特殊的规定。组件和类的关系:符合某种规范的类的组合构成组件
@Configuration作用是告诉SpringBoot这是一个配置类 == 配置文件
之前的Spring学习中,我们通过XML配置文件进行管理bean
通过@Configuration注解可以不用写XML配置文件,将它写在类上面可以把这个类当成配置类来用。对象的管理在这个配置类中进行
@Configurationpublic class Myconfig {}
@Configuration(proxyBeanMethods = true),默认值是true的。那么它有什么用呢?
Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
组件依赖必须使用Full模式默认。其他默认是否Lite模式
我们打印Myconfig对象可以看到是EnhancerBySpringCGLIB,这个就代表它是一个被SpringCGLIB增强了的代理对象
com.caq.boot.config.Myconfig
E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB
EnhancerBySpringCGLIB
dfb5b12f@55f45b92
如果代理对象调用配置类中注册组件使用的方法返回值一定是单实例
********配置类******** @Configuration(proxyBeanMethods = true) public class Myconfig { @Bean public User user01(){ return new User("zs",12); } @Bean("tiger") //这个我们自定义一个名字,不用方法名作为实例的名字了 public Pet animal01(){ return new Pet("li"); } } ********主程序类******** @SpringBootApplication public class MainApplication { public static void main(String[] args) { //1.返回值是IOC容器 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); Myconfig myconfig = run.getBean(Myconfig.class); System.out.println("对配置类中的这个组件注册方法调用看获取到的对象是不是同一对象"); User user02 = myconfig.user01(); User user03 = myconfig.user01(); System.out.println(user02==user03); } } ********测试结果******* ... com.caq.boot.config.Myconfig$$EnhancerBySpringCGLIB$$3ea98f23@1d81e101 对配置类中的这个组件注册方法调用看获取到的对象是不是同一对象 true
2.2.3 @Import
和@Bean功能类似,都是注册组件的
@Import({User.class, DBHelper.class})作用是给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
@SpringBootApplication public class MainApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); String[] beanNamesForType = run.getBeanNamesForType(User.class); for (String s : beanNamesForType) { System.out.println(s); } } } *************打印结果************ com.caq.boot.bean.User user01
2.2.4 @Conditional
@Conditional就是条件装配:满足Conditional指定的条件,则进行组件注入
@ConditionalOnBean(name = “tiger”)如果容器中有tiger这个组件才会执行下面的配置
@ConditionalOnMissingBean(name = “tiger”)如果容器中没有tiger这个组件才会执行下面的配置
//
@Import({User.class, DBHelper.class}) @Configuration(proxyBeanMethods = true) @ConditionalOnBean(name = "tiger") //@ConditionalOnMissingBean(name = "tiger") public class Myconfig { @Bean public User user01(){ return new User("zs",12); } // @Bean("tiger") public Pet animal01(){ return new Pet("li"); } }
2.2.5 @ImportResource
可以引入xml配置文件中的bean
======================beans.xml========================= <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="zs" class="com.caq.boot.bean.User"> <property name="name" value="zhangsan"></property> <property name="age" value="18"></property> </bean> <bean id="dog" class="com.caq.boot.bean.Pet"> <property name="name" value="tomcat"></property> </bean> </beans>
@ImportResource("classpath:beans.xml") public class MyConfig {}
2.2.6 @ConfigurationProperties
将我们的类和配置文件进行绑定
@ConfigurationProperties(prefix = “mycar”)和配置文件绑定,prefix是和配置文件中的前缀对应
配置绑定可以理解为字面意思,将要配置给对象的属性写在配置文件中。通过@ConfigurationProperties注解来实现赋值
**************************car的实体类******************* //只有在容器中的组件才有SpringBoot提供的功能 @Component @ConfigurationProperties(prefix = "mycar") public class Car { private String brand; private String price; public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } @Override public String toString() { return "Car{" + "brand='" + brand + '\'' + ", price='" + price + '\'' + '}'; } } **********************web层代码*************************** @RestController //@RestController是@ResponseBody的结合@Controller public class Controller { @RequestMapping("/hello") public String handle01() { return "Hello SpringBoot 2 !" + "你好"; } @Autowired Car car; @RequestMapping("/car") public Car car() { return car; } }
运行springboot程序,访问可以发现成功把配置文件中的值注入到对象里了,绑定成功了
第二种配置文件绑定的方式
@Component+@ConfigurationProperties这种方式需要手动的把要绑定的类注册到容器中,如果是外部的类的话很不方便
@EnableConfigurationProperties(Car.class)+@ConfigurationProperties
其中@EnableConfigurationProperties(Car.class)能实现
1.开启car配置绑定功能
2.把这个car组件自动注册到容器中
@Configuration @EnableConfigurationProperties(Car.class) public class Myconfig {} @ConfigurationProperties(prefix = "mycar") public class Car {}
2.3 自动配置原理入门
2.3.1 回顾注解
什么是元注解?
元注解是可以注解到注解上的注解,或者说元注解是一种基本注解,但是它能够应用到其它的注解上面。它的作用和目的就是给其他普通的标签进行解释说明的。
Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。
它的取值如下:
RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
@Documented有什么用?
@Documented 保存到javadoc
顾名思义,这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去。(Javadoc用于描述类或者方法的作用)
@Target 限定使用场景
Target 是目标的意思,@Target 指定了注解运用的地方。当一个注解被 @Target 注解时,这个注解就被限定了运用的场景。类比到标签,原本标签是你想张贴到哪个地方就到哪个地方,但是因为 @Target 的存在,它张贴的地方就非常具体了,比如只能张贴到方法上、类上、方法参数上等等。
@Target 有下面的取值:
ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
ElementType.CONSTRUCTOR 可以给构造方法进行注解
ElementType.FIELD 可以给属性进行注解
ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
ElementType.METHOD 可以给方法进行注解
ElementType.PACKAGE 可以给一个包进行注解
ElementType.PARAMETER 可以给一个方法内的参数进行注解
ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
@Inherited 注解继承
Inherited 是继承的意思,它的意思是@Inherited注解了B注解,B再注解别人,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解,代码来解释。
@Inherited @Retention(RetentionPolicy.RUNTIME) @interface Test {} @Test public class A {} public class B extends A {}
注解 Test 被 @Inherited 修饰,之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解。
2.3.2 @SpringBootConfiguration
这是注解@SpringBootConfiguration的源码,因为@Inherited注解
所以@SpringBootApplication注解的类继承了这个超类的三个注解@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
之后我们在分别看这三个注解
原来@SpringBootConfiguration是@Configuration是用来表示类为配置类的
2.3.3 @ComponentScan
Spring部分就学过,是知道扫描哪些,spring注解
2.3.4 @EnableAutoConfiguration
EnableAutoConfiguration的目的是启动SpringBoot的自动配置机制。
@AutoConfigurationPackage
我们可以发现,依靠的还是@Import注解,再点进去查看,我们发现重要的就是以下的代码:
它的作用就是在默认的情况下将主配置类(@SpringBootApplication)的所在包及其子包里边的组件扫描到Spring容器中。
这个扫描的和Component扫描的对象不同
比如说,你用了Spring Data JPA,可能会在实体类上写@Entity注解。这个@Entity注解由@AutoConfigurationPackage扫描并加载,而我们平时开发用的@Controller/@Service/@Component/@Repository这些注解是由ComponentScan来扫描并加载的。
@Import(AutoConfigurationImportSelector.class)
使用Import自动导入所有符合自动配置条件的Bean定义并加载到IOC容器
2.3.5 总结
pringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定
生效的配置类就会给容器中装配很多组件
只要容器中有这些组件,相当于这些功能就有了
定制化配置
用户直接自己@Bean替换底层的组件
用户去看这个组件是获取的配置文件什么值就去修改。















