1、忘记
- @RestController返回的是一个字符串 =@RequestMapping+@responseBody
- SpringBoot可以实现热部署,不需要导入依赖就可以实现(勾选SpringBootDevTools可以实现热部署)
- 更改热部署,在新建项目的时候设置,不用测试每次重启
- 设置banner.text,放置resources包下
- 更改项目端口号,在配置文件下更改 server.port=8081
- Aware是一个接口,一个标记超接口,指示 bean 有资格通过回调样式方法由特定框架对象的 Spring 容器通知。
Aware 接口是一个具有标识作用的超级接口,指示 bean 是具有被 Spring 容器通知的能力,通知的方式是采用回调的方式。Aware 接口是一个空接口,具体的实现由各个子接口决定,且该接口通常只包含一个单个参数并且返回值为void的方法。可以理解就是 set 方法。该方法的命名方式为 set + 去掉接口名中的 Aware 后缀,即 XxxAware 接口,则方法定义为 setXxx(),例如 BeanNameAware(setBeanName),ApplicationContextAware(setApplicationContext)。
注意,仅实现Aware接口,不会提供任何默认功能,需要明确的指定实现哪个子接口。
我们可以得出实现这些 Aware 接口的Bean在被初始化之后,可以获取相对应的资源。例如实现BeanFactoryAware的Bean在实例化后,Spring容器将会注入BeanFactory的实例。
ApplicationContextAware那这个Aware是在什么时候被激活的呢?逻辑位于ApplicationContextAwareProcessor的invokeAwareInterfaces方法里
当前 bean 实现了什么接口,就给这个 bean 设置相对应的对象实例。至于ApplicationContextAwareProcessor 类是一个BeanPostProcessor。
2、原理(自动配置)
启动器 spring-boot-starter
`
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-starter-web </artifactId>
`
springboot-boot-starter-xxx:就是spring-boot的场景启动器
spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件;
SpringBoot将所有的功能场景都抽取出来,做成一个个的starter(启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可 ;我们未来也可以自己自定义 starter;
一、主启动类
@SpringBootApplication (自动配置的核心,启动是run)
作用:标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;
进入这个注解:可以看到上面还有很多其他注解!
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {
@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}),
@Filter(type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class})})
public @interface SpringBootApplication
{ // ......}
1.1 @ComponentScan
这个注解在Spring中很重要 ,它对应XML配置中的元素。
作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中
1.2 @SpringBootConfiguration
作用:SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;
我们继续进去这个注解查看
这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;
里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!
1.3 @EnableAutoConfiguration
- @AutoConfigurationPackage
以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 ;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;
点进注解接续查看:
@AutoConfigurationPackage :自动配置包
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage
@import :Spring底层注解@import , 给容器中导入一个组件
Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 ;
- @Import(AutoConfigurationImportSelector.class) 给容器导入组件,自动导入选择器选择了什么样的东西?
//通过2个方法
getAutoConfughrationEntry()获得自动配置的实体
getCandidateConfigurations()获取候选的配置 标注了@EnableAutoConfiguration的类
所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类 , 然后将这些都汇总成为一个实例并加载到IOC容器中。
结论:
- SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
- 将这些值作为自动配置类(@confuguration,满足一定的条件才进行创建bean对象)导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;
- 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;
- 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;
- 有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;
SpringApplication.run分析
分析该方法主要分两部分,一部分是SpringApplication的实例化,二是run方法的执行;
SpringApplication
实际上是开启了一个服务
这个类主要做了以下四件事情:
1、推断应用的类型是普通的项目还是Web项目 (java普通项目运行完就结束了,web导进去还会接着运行,是否配置加内置的tomcat)
2、查找并加载所有可用初始化器 , 设置到initializers属性中
3、找出所有的应用程序监听器,设置到listeners属性中
4、推断并设置main方法的定义类,找到运行的主类
3、yaml语法(配置文件)
可以配置哪些东西?
3.1 配置文件
SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的
- application.properties
-
- 语法结构 :key=value
- application.yml
-
- 语法结构 :key:空格 value 配置文件的作用 : 修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;
比如我们可以在配置文件中修改Tomcat 默认启动的端口号!测试一下!
使用yml的语法合适
server :
port : 8081 (8081前有一个空格)
## yaml基础语法
说明:语法要求严格!
1、空格不能省略
2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
3、属性和值的大小写都是十分敏感的。
3.2 使用yml文件给类的属性注入值,之前的做法使用@value
- 首先,在yml文件中创建一个类
person:
name: qinjiang
age: 3
happy: false
birth: 2000/01/01
maps: {k1: v1,k2: v2}
lists:
- code
- girl
- music
dog:
name: 旺财
age: 1
- 将属性值注入到对应的实体类中
@Component //注册bean
@ConfigurationProperties(prefix = "person") //加载配置文件
person是对应的在appication.yml的配置类的名字
- 加载需要配置对应的依赖
<!-- 导入配置文件处理器,配置文件进行绑定就会有提示,需要重启 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
3.3 对应的注解
@PropertySource : 加载指定的配置文件;
@configurationProperties:默认从全局配置文件中获取值;
1、@ConfigurationProperties只需要写一次即可 , @Value则需要每个字段都添加
2、松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下
3、JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性
4、复杂类型封装,yml中可以封装对象 , 使用value就不支持
配置yml和配置properties都可以获取到值 , 强烈推荐 yml;
如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;
如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!
3.4 JSR303数据校验及多环境切换
3.4.1 JSR303数据校验
Springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。我们这里来写个注解让我们的name只能支持Email格式;
@Component //注册bean
@ConfigurationProperties(prefix = "person")
@Validated //数据校验
public class Person {
@Email(message="邮箱格式错误") //name必须是邮箱格式
private String name;
}
3.4.2 多环境切换
application-test.properties 代表测试环境配置
application-dev.properties 代表开发环境配置
但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;
我们需要通过一个配置来选择需要激活的环境:
#比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试;
#我们启动SpringBoot,就可以看到已经切换到dev下的配置了;
spring.profiles.active=dev
spring:
thymeleaf:
mode: HTML
profiles:
active: dev
messages:
basename: i18n/messages (国际化)
3.4.3 自动配置原理再品
//表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件;
@Configuration
//启动指定类的ConfigurationProperties
功能;
//进入这个HttpProperties查看,将配置文件中对应的值和HttpProperties绑定起来;
//并把HttpProperties加入到ioc容器中
@EnableConfigurationProperties({HttpProperties.class})
//Spring底层@Conditional注解
//根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效;
//这里的意思就是判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication
类似于上面通过@ConfigurationProperties进行对应的属性,yml能对应的也是@Configurationproperties所对应的配置,才能添加对应的配置
这就是自动装配的原理!
精髓
1、SpringBoot启动会加载大量的自动配置类
2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
xxxxAutoConfigurartion:自动配置类; 给容器中添加组件
xxxxProperties:封装配置文件中相关属性; 怎么修改属性呢?适应SprigBoot的配置文件进行修改
总结:自动装配了大量的配置类,但不是所有的配置的类都会生效,在底层的时候有 @Conditional 注解来判定对应的条件。默认的装配的类的属性也是默认的,底层是有 @ConfigurationProperties 我们可以通过Spingboot的配置文件来修改默认的属性。可以在Spring的配置文件中设置debug=true 来打印出哪些配置类是生效的
Positive matches:(自动配置类启用的:正匹配)
Negative matches:(没有启动,没有匹配成功的自动配置类:负匹配)
Unconditional classes: (没有条件的类)
怎么让他生效呢?导入对应的依赖就可以,对应的starter