SpringBoot 的原理


SpringBoot 的主要作用有两个:依赖管理和自动配置,需要了解它们的原理和如何修改默认配置

依赖管理

依赖存放在父工程中,就是 spring-boot-starter-parent

而其父工程的父工程 spring-boot-dependencies 中保存了所有依赖以及版本号,大大减少了版本问题

如果想要修改依赖的版本,在 pom 文件中 properties 下增加对应依赖版本即可

有了 springboot 的版本仲裁,以后写项目的时候应该将依赖的版本写在父 pom 文件中,子文件只用来导入依赖

配置类 @Configuration 与 proxyBeanMethods

使用 @Configuration 注解来将一个类定义为配置类,它的功能类似与配置文件

该注解的底层长这样

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";

    boolean proxyBeanMethods() default true;
}

所以配置类也是 spring 的一个组件,在该类的方法上加入 @Bean 注解,还将方法的返回值注册为 bean,这里面有一个比较重要的属性 proxyBeanMethods ,默认为 true ,该属性的意思是表示这个组件是不是代理 bean 的组件,如果是 true 的话,那么这个配置类就会被 CGLIB 代理了,如果是 false 的话,那么就不会被代理

那代理之后的类增加了什么功能呢?当我们使用代理对象的时候,调用它的方法,他会检测容器中是不是有了这样的组件,如果有,则不再新建组件,直接将已经有的组件返回。如果说没有的话,才会新建组件。这样保证了容器中的组件始终就保持单一性。不过这也有一个不好的地方,那就是每次都要检测,会降低速度。当不是代理对象的时候,则不会检测,直接创建新的组件了

因此直观的说,proxyBeanMethods 为 true 时,表示 full (全)模式,保证组件单例;proxyBeanMethods 为 false 时,表示 lite (轻)模式,系统启动快

创建时文件以及目录作用

.idea 目录用来存放 idea 配置
.mvn 目录用来存放 maven 配置(可删除,没影响)
.gitignore 用 git 做版本控制时,用这个文件控制哪些文件或文件夹不被提交(不用 git 的话可删除,没影响)
HELP.md md是一种文档格式 这个就是你项目的帮助文档(可删除,没影响)
mvnw linux上处理mevan版本兼容问题的脚本(可删除,没影响)
mvnw.cmd windows 上处理mevan版本兼容问题的脚本(可删除,没影响)
springboot.iml 有的文件每个导入IDEA的项目都会生成一个项目同名的 .iml文件,用于保存你对这个项目的配置(删了程序重新导入后还会生成,但由于配置丢失可能会造成程序异常)

自动配置原理

主类与 @SpringBootApplication

主类是 SpringBoot 的一部分,删掉的话无法正常执行程序,主类包括 @SpringBootApplication 注解以及 run 方法

SpringApplication.run(HelloworldApplication.class, args)

run 方法返回一个 IOC 容器,容器中存放的 bean 其实是组件,即我们在开发过程中需要的类,而且这些组件一般指我们的实体配置类以及基础类

@SpringBootApplication 是程序的一部分,这个注解会自动加在主类上,它是一个联合注解,点入@SpringBootApplication:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {...}

它主要由三个注解形成:

1,@EnableAutoConfiguration:自动装配(enable:使能够)

2,@ComponentScan(XXX):扫描主类注解所在的同级目录下的其他包中用户定义的 bean,在里面配置其他的东西可以让其扫描其他包下的注解

3,@SpringBootConfiguration:允许用户定义bean或者配置类(这个注解被@Configuration注解,指这个类是配置类,而@Configuration是一个Component)

自动装配的注解 @EnableConfigurationProperties 与 @ConfigurationProperties

点入@EnableAutoConfiguration中,发现

//这个自动注册包
@AutoConfigurationPackage
//这个导入配置选择类
@Import({AutoConfigurationImportSelector.class})

AutoConfigurationImportSelector类有多种功能,主要是读取所有注册在MATE-INF/spring.factories文件中的全限定名并且读取这些全限定名所代表的文件,比如:

org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer,\
org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\

XXXAutoConfiguration一定包含 @Configration 注解,这让它是一个配置类,配置类被Component注释,表示它也是一个组件被加载到IOC容器中

部分自动配置类可以提供 @EnableConfigurationProperties 注解找到它们配置的配置类,这个注解表示把里面装的类丢到容器中去并且可以在yaml文件中配置相应的属性,因为有些三方包不会有 @ConfigurationProperties 注解,这让用户可以使用yaml配置文件自定义配置类来覆盖部分的默认配置

//这个注解表示把里面的那个类注册为一个组件
@EnableConfigurationProperties({CacheProperties.class})

这个组件上面有 @ConfigurationProperties 注解,这个注解表示把自己丢到容器中去并且可以在yaml文件中配置相应的属性,让用户可以自定义配置里面的属性

@ConfigurationProperties(prefix = "spring.cache")

在spring-boot-autoconfigure的jar包下的非MATE-INF包中可以找到它们,你可以直接找到它们

所有的配置类在启动时都会生效吗 @ConditionalXXX

所有的自动配置类(写在MATE-INF/spring.factories中的类)在SpringBoot启动时都会被遍历到,它们会被扫描并加载

但是它们都会有 @ConditionalOnXXX 条件装配注解,这个注解表示,只有在对应条件满足的时候配置才会生效,比如只有导入对应启动器时才能生效、只有对应实体配置类存在才生效

//这是CacheManager配置类的注解
@ConditionalOnClass({CacheManager.class})
@ConditionalOnBean({CacheAspectSupport.class})
@ConditionalOnMissingBean(
    value = {CacheManager.class},
    name = {"cacheResolver"}
)

这么做会避免读取过多的 bean

使用配置文件对实体配置类进行配置

所有的配置文件必须叫 application,后缀可变,配置文件可以设置在4个位置

可以使用原来的.properties(财产、所有物)文件进行配置,在对应类的上面使用注解@PropertySource(value = “文件全限地址”)来配置文件

也可以使用 yaml 文件配置,在类上使用 @ConfigurationProperties(prefix = “对象名称”)

#对象
student:
#  对象属性
  name: xie
  age: 20
#  数组
  book:
    - b1
    - b2
    - b3

prefix意思是前缀

你也可以使用 @Value 使用来读取比较简单的配置信息:

@Value("${integerValue}")
Integer integer;

对应的配置文件

integerValue: 12

@Autowired 与 @Resource 的区别

Autowired 属于 Spring 内置的注解,默认的注入方式是根据类型进行匹配,通常被称为 byType。当它通过类型找到多个对象的时候,会自动转化为 byName 形式(根据名称进行匹配),这个名称通常就是类名的首字母小写。还找不到的话,那就只能报错了

Resource 属于 JDK 提供的注解,默认注入方式为 byName。如果无法通过名称匹配到对应的 Bean 的话,注入方式会变为 byType

当然这两种都存在找不到的风险,这时候就需要指定对应名称了,两种注解都有指定名称的方式(qualifie 是合格的意思)

@Autowired 
@Qualifie("userService") 
...

@Resource("userService")
...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值