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")
...