SpringBoot-基础入门篇

S p r i n g B o o t SpringBoot SpringBoot

底层注解

容器功能

2.1、组件添加

@Configuration详解

下面是我们用SpringXML的方式向容器中添加组件的方法:
SpringBoot-基础入门篇_第1张图片
下面是使用SpringBoot来声明组件类的方式:
@Configuration翻译为配置。
将一个类设置为配置文件,将该类下面的方法设置为Bean组件
SpringBoot-基础入门篇_第2张图片

//告诉SpringBoot这是一个配置类 == 配置文件
//相当于 (Spring配置文件)MyConfig.xml
@Configuration
public class MyConfig {
    //给容器中添加组件.以方法名作为组件的id ↓
    //相当于 
    @Bean
    public Cat cat01(){
        return new Cat();
    }
    /*相当于
     
        
     
    */
    @Bean
    public Pet tomcat(){
        return new Pet("奔驰A200L");
    }
}

SpringBoot-基础入门篇_第3张图片
自定义Bean的id
在这里插入图片描述
SpringBoot-基础入门篇_第4张图片
此处创建的Bean组件默认是单例的,无论从容器中获得多少次都一样。
id错误的错误信息
在这里插入图片描述
获得自定义的配置Bean类对象实例(默认单例)
SpringBoot-基础入门篇_第5张图片
配置类也是IOC中的Bean对象组件
在这里插入图片描述
SpringBoot2后@Configuration新增的注解–>@proxyBeanMethods

SpringBoot-基础入门篇_第6张图片
@proxyBeanMethods:代理bean的方法。
下面是控制台输出的配置类对象:
com.atguigu.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 EnhancerBySpringCGLIBf59b6e0c@8dfe921
可以看到该配置类是SpringCGLIB创建的加强过的代理类。
这相当于我们获取到的本身就是代理对象,然后代理对象调用注册组件方法,SpringBoot默认逻辑:如果@Configuration(proxyBeanMethods = true)。
那就是代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
保持组件单实例,如果把proxyBeanMethods设置为false,则调用的方法返回的对象不再是同一个,并且获得到的配置类也不再是代理对象↓
在这里插入图片描述
该注解和组件依赖有很大的关系,如果一个类依赖了另外一个类,在该类中直接调用获得对方类实例的方法时,如果proxyBeanMethod是true,则获取的是正确的,如果是false则对应不上,看如下截图
SpringBoot-基础入门篇_第7张图片
如果是true,则用户的宠物就是容器中的宠物,如果是false,则用户的宠物不是容器中的宠物,每次调用获得宠物对象的方法都会获得不同的宠物实例。
在这里插入图片描述
SpringBoot-基础入门篇_第8张图片
默认是全模式,也就是默认为true,代理对象调用方法,创建的对象都是单例的。
设置建议
如果只是单纯注册组件,并且组件之间没有依赖,则推荐设置为false。
在底层中,使用轻量级模式较多。

@Import注解导入组件

在这里插入图片描述
SpringBoot-基础入门篇_第9张图片
@Import注解

SpringBoot-基础入门篇_第10张图片

//@Import注解可以创建出下面两个类型的无参构造器,用以调用
//相当于给容器中,自动创建出这两个类型的组件
@Import({Cat.class, DBHelper.class})

SpringBoot-基础入门篇_第11张图片
结果

ch.qos.logback.core.db.DBHelper@415e0bcb

在这里插入图片描述
可以看到,IOC容器里确实有了通过@Import注解所声明的对象组件了。
在这里插入图片描述

@Conditional条件装配

条件装配:满足Conditional指定的条件,则进行组件注入
SpringBoot-基础入门篇_第12张图片
@Condition注解派生了很多注解,这些注解用来具体指定功能

常见的@Conditional注解派生注解
@ConditionalOnBean:当容器中存在我们指定的Bean时,我们才干某些事情
@ConditionalMissingBean:当容器没有这个Bean组件的时候,我们才干某些事情
@ConditionalOnClass:当容器中有某一个类的时候,我们才干某些事情
@ConditionalMissingClass:当容器没有这个类的时候,我们才干某些事情
@ConditionalOnResource:项目路径中,存在一个资源,我们才干某些事情
@ConditionalOnJava:是指定的Java版本号时,我们才干某些事情
@ConditionalOnWebApplication:当我们的应用是Web应用时,我们才干某些事情
@ConditionalOnNotWebApplication:当我们的应用不是Web应用时,我们才干某些事情
@ConditionalOnSingleCandidate:当我们指定的实例在容器中只有一个时,我们才干某些事情
@ConditionalOnProperty:当配置文件中配置了某个属性的时候,我们才干某些事情

@ConditionOnBean注解

在这里插入图片描述
上卖弄的API是判断容器中是否包含该Bean组件,此处我们注释了BenChi的@Bean注解,所以是false
SpringBoot-基础入门篇_第13张图片
使用OnBean注解来判断

    @ConditionalOnBean(name = "tom")
    @Bean("Tomcat")
    public Cat cat01(){
        return new Cat();
    }

2.2、原生配置文件引入

@ImportResource
该注解翻译为导入资源
如果我们写了beans.xml,也就是Spring形式的IOC容器配置文件,此时如果只是beans.xml文件的话,SpringBoot是无法识别该配置文件的,我们需要用到@ImportResource注解,注解传入配置文件的路径
SpringBoot-基础入门篇_第14张图片

增加@ImportResource注解

@ImportResource("classpath:beans.xml")
public class MyConfig {

SpringBoot-基础入门篇_第15张图片

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3、底层注解-@ConfigurationProperties配置绑定

如果我们需要让Java类的值和配置文件的值进行绑定,在传统的做法中则是获得配置文件的输入流,然后进行遍历和字符串拼接,比较麻烦,尤其是在配置条目非常多的时候,而SpringBoot则可以通过注解非常迅速的完成这些操作。
SpringBoot-基础入门篇_第16张图片

//组件标识注解 --> 只有在容器中的组件,才会拥有SpringBoot提供的强大功能
@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {

SpringBoot-基础入门篇_第17张图片
运行结果

@RestController
public class HelloController {
    @Autowired
    Car car;//使用自动注入
    @RequestMapping("/car")
    public Car car(){
        return this.car;
    }

SpringBoot-基础入门篇_第18张图片
该注解的使用总结:创建一个POJO类,在该类上标识该注解,在注解中传入要赋值对应前缀的配置文件属性前缀,设置后在控制器里进行该类定义和自动装配,然后输出该类即可,只要有配置文件就可以自动装配。
使用@EnableConfigurationProperties注解将Car类开启属性绑定,并自动注册到容器中
为什么要这么做,我们不是有@Component注解将Car类标识为了容器组件了吗?这么做会不会多此一举呢?
并不会,如果是第三方Jar包的类,我们怎么可能给这个类标记上@Component呢,所以我们尽量要用@EnableConfigurationProperties注解来自动绑定和注册,并且该注解直接传入类的class对象即可。如下展示。
基于增加@EnableConfigurationProperties注解的改动

在这里插入图片描述
SpringBoot-基础入门篇_第19张图片
这样做的泛用性更高一些,比较推荐,注意,上面的修改并没有去掉@ConfigurationProperties(prefix = “mycar”)注解,只是删除了@@Component注解,然后在配置类增加了@EnableConfigurationProperties注解。
上面两种组合都可以完成,但是推荐第二种。

源码分析

自动配置-自动包规则原理

首先我们前面有说到:
@SpringBootApplication是由3个注解组合而成,也就是说,我们在使用@SpringBootConfiguration时,也可以写组成该注解的那3个注解,效果一致,只是@SpringBootApplication包含了这3个注解
三个注解如下:

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

@SpringBootConfiguration的作用是表示这是一个配置类
@ComponentScan就是包扫描
@EnableAutoConfiguration是核心功能的注解,下面将详细介绍该注解。

@EnableAutoConfiguration

英文翻译 --> EnableAutoConfiguration:启用自动配置
该注解是组成@SpringBootApplication注解的核心注解,该注解也是其他注解组成而成,它的组成注解如下:

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})

AutoConfigurationPackage:自动配置包
AutoConfigurationImportSelector:自动配置导入选择器

@AutoConfigurationPackage
自动配置包,指定了默认的包规则
源码:

@Import({Registrar.class})
public @interface AutoConfigurationPackage {

@Import注解就是给容器导入一个组件,这里Import注册了一个组件:Registrar类,该类表示的是批量注册。

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
        Registrar() {
        }

        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
        }
        public Set<Object> determineImports(AnnotationMetadata metadata) {
            return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata));
        }
    }

利用Registrar给容器导入一系列组件

//该方法传入了两个参数
//AnnotationMetadata表示注解的元信息
//
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
        }

在这里插入图片描述
方法体根据注解获得包名,相当于得到了主类所在的包名,把这个包名封装到了一个String数组里,然后AutoConfigurationPackages.register()注册进去,相当于Registrar类把某一个包下的所有组件批量注册起来
SpringBoot-基础入门篇_第20张图片

也就是说组成
@EnableAutoConfiguration
注解的第一个注解@AutoConfigurationPackage的功能就是利用批量注册类来批量注册组件,根据元注解信息获得包路径,然后批量注册该包路径下的组件(该包路径是SpringBootApplication所在的包)
在这里插入图片描述
@EnableAutoConfiguration的第二个组成注解:

@Import({AutoConfigurationImportSelector.class})

核心源码

AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);

在这里插入图片描述
利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
调用List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);获取到所有需要导入到容器中的配置组件。
利用Spring的加载工厂来加载这些组件。
在这里插入图片描述
在这里插入图片描述
上面方法最终得到加载所有的组件。
从META-INF/spring.factories位置来加载一个文件
默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
SpringBoot-基础入门篇_第21张图片
上面的包里也有META-INF/spring.factories
SpringBoot-基础入门篇_第22张图片
文件里面写死了spring-boot一启动就要给容器加载的所有配置。
SpringBoot-基础入门篇_第23张图片
按需开启:
虽然我们127个场景的所有自动配置启动的时候默认全部加载,但是最终会按需配置:
SpringBoot-基础入门篇_第24张图片
可以看到AOP类里开启了满足条件再执行的注解,只有导入了AOP的包,该组件下面的代码只会执行,执行了这些代码,自动配置才会生效。

SpringBoot-基础入门篇_第25张图片
批处理也不能生效,因为没有导入这些包,也就是没有满足这些定义的条件。

SpringBoot-基础入门篇_第26张图片
这些类都没有导入,都是爆红了的,所以它们都没有生效。
虽然这些类都一股气的导入了,但是要按照SpringBoot的按需加载来实际的注册。
总结:按需加载,条件装配

自动配置流程

SpringBoot-基础入门篇_第27张图片
在这里插入图片描述
在自动配置中,matchIfMissing是默认认为配置的意思,就算没有也认为你有,此处的AOP功能,上面的条件不符合,但是有一处简单的AOP场景符合了条件,如下。
SpringBoot-基础入门篇_第28张图片
**AutoConfiguration是SpringBoot定义的一种自定义配置类的规则。
SpringBoot-基础入门篇_第29张图片
底层帮我们配置好了SpringMVC
SpringBoot-基础入门篇_第30张图片
SpringBoot-基础入门篇_第31张图片
当传入文件解析器对象时,如果文件名不符合规范,则SpringBoot会纠正,重新返回给容器,因为方法名是规范的,以方法注入组件,不设置Bean注解的值时,则默认使用方法名作为容器中Bean组件的id。
编码配置
SpringBoot-基础入门篇_第32张图片
SpringBoot-基础入门篇_第33张图片
SpringBoot-基础入门篇_第34张图片
SpringMVC解决编码问题。
修改默认配置
SpringBoot默认会在底层配好所有的组件,但是如果用户自己配置了以用户的优先

在这里插入图片描述
因为@ConditionlOnMissingBean注解,该注解表示,当容器中没有这个东西的时候才会自动配置。SpringBoot-基础入门篇_第35张图片
上面相当于自定义了编码过滤器,此时容器不再是没有编码过滤器,那么SpringBoot也就不会再默认自动配置编码过滤器。
总结
SpringBoot-基础入门篇_第36张图片
在这里插入图片描述
SpringBoot-基础入门篇_第37张图片

最佳实践-SpringBoot应用如何编写

  • 引入场景依赖
  • 查看自动配置了哪些
  • 是否需要修改
    • 参照文档修改配置项
    • 自定义加入或者替换组件

在这里插入图片描述
debug=true相当于在控制台打印自动配置报告。
在这里插入图片描述

SpringBoot-基础入门篇_第38张图片

使用自定义配置文件来修改SpringBoot启动的头图

在我们定义的SpringBoot统一配置文件中,写如下配置:
注意这个文件名必须是英文的,还有就是bug.jpg也不行,比较奇怪?

#默认值是 banner.jpg 我们可以把我们的文件修改为banner.jpg 这样可以直接找到
#spring.banner.image.location=classpath:banner.jpg
#自定义↓
spring.banner.image.location=classpath:222.jpg

SpringBoot-基础入门篇_第39张图片
SpringBoot-基础入门篇_第40张图片

Lombok简化开发

首先我们在pom文件中则,增加一组依赖

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

去插件市场下载lombok插件
SpringBoot-基础入门篇_第41张图片
如果搜索不到Lombok,就需要设置一下:
插件市场旁边有个设置按钮,点击它在展开的选项中点击 HTTP Proxy Settings
在打开的页面中点击“Check connection”,意思是检查连接,然后点击该按钮进行设置。
输入插件网站的地址

http://plugins.jetbrains.com/ 

点击确定,弹出下面对话框就表示设置成功↓
SpringBoot-基础入门篇_第42张图片

我们找到先前的Car POJO类,删除该类里的getter和setter方法,还有toString方法。
SpringBoot-基础入门篇_第43张图片
在该类上增加@Data注解↓

在这里插入图片描述
SpringBoot-基础入门篇_第44张图片
上面没有标识为注解是因为配置类中已经使用自动配置属性注解
SpringBoot-基础入门篇_第45张图片
SpringBoot-基础入门篇_第46张图片

dev-tools

热更新,没什么卵用
导入依赖:

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-devtoolsartifactId>
    <optional>trueoptional>
dependency>

加入后,按Ctrl+F9,表示项目重新编译,编译后devtools会帮我们重写部署。
已亲测,请自行测试!
总结:没用

Spring Initailizr

省流:没用,自己搁机房玩玩还差不多
快速创建SpringBoot项目↓
SpringBoot-基础入门篇_第47张图片

SpringBoot-基础入门篇_第48张图片
SpringBoot-基础入门篇_第49张图片
勾选想要配置注册的开发场景
SpringBoot-基础入门篇_第50张图片
SpringBoot-基础入门篇_第51张图片
SpringBoot-基础入门篇_第52张图片

SpringBoot-基础入门篇_第53张图片

SpringBoot-基础入门篇_第54张图片
static目录是存放静态资源:css文件、Js文件等
templates目录是存放页面资源:页面
SpringBoot-基础入门篇_第55张图片
SpringBoot-基础入门篇_第56张图片

你可能感兴趣的:(私人,spring,boot,java,spring)