注解
@SpringBootApplication 表示一个配置类:它声明一个或多个@Bean 方法,同时触发自动配置和组件扫描。这是一个组合注解相当于声明了@Configuration、@EnableAutoConfiguration 和@ComponentScan
@SoringBootApplication 三个注解
@interface 准确的说它不是一个接口,而是一个新的注释类型-注释类,它的类名就是注释名
@Target
@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Target {/*** Returns an array of the kinds of elements an annotation type* can be applied to.* @return an array of the kinds of elements an annotation type* can be applied to*/ElementType[] value();}
官方文档注释:
@Target 官方注释
它的意思是说,用了@Target 注解的注解,可以被用在哪些作用域中,有哪些作用域需要到java.lang.annotation.ElementType 里面去找
public enum ElementType {/** 用在描述类、接口(包括注解类型)或枚举 */TYPE,/** 用在字段声明(包括枚举) */FIELD,/** 用于方法上 */METHOD,/** 用在参数上 */PARAMETER,/** 用在构造器(又叫构造方法)上 */CONSTRUCTOR,/** 用在局部变量上 */LOCAL_VARIABLE,/** 用在描述注释上 */ANNOTATION_TYPE,/** 用在包上 */PACKAGE,/** 从1.8开始支持,自定义类型参数上 */TYPE_PARAMETER,/** 从1.8开始支持,对类型注解 */TYPE_USE}
@Retention
/*** Indicates how long annotations with the annotated type are to* be retained. If no Retention annotation is present on* an annotation type declaration, the retention policy defaults to* {@code RetentionPolicy.CLASS}.** <p>A Retention meta-annotation has effect only if the* meta-annotated type is used directly for annotation. It has no* effect if the meta-annotated type is used as a member type in* another annotation type.** @author Joshua Bloch* @since 1.5* @jls 9.6.3.2 @Retention*/@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Retention {/*** Returns the retention policy.* @return the retention policy*/RetentionPolicy value();}
官方文档注释:
@Retention 官方注释
@Retention 是定义该注解的生命周期有多久 ,而决定它的生命周期在一个枚举类型的RetentionPolicy里

RetentionPolicy
- SOURCE:在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释,在.class文件中不会保留注解信息
- CLASS:在class文件中有效(即class保留),保留在.class文件中,但是当运行Java程序时,他就不会继续加载了,不会保留在内存中,JVM不会保留注解。如果注解没有加Retention元注解,那么相当于默认的注解就是这种状态。
- RUNTIME:在运行时有效(即运行时保留),当运行 Java程序时,JVM会保留注释,加载在内存中了,那么程序可以通过反射获取该注释。
@Documented (很少)
/*** Indicates that annotations with a type are to be documented by javadoc* and similar tools by default. This type should be used to annotate the* declarations of types whose annotations affect the use of annotated* elements by their clients. If a type declaration is annotated with* Documented, its annotations become part of the public API* of the annotated elements.** @author Joshua Bloch* @since 1.5*/@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Documented {}
官方文档注释:
@Documented 官方注释
用于指定被该元注解修饰的注解类将被javadoc工具提取成文档。默认情况下,javadoc是 不包括注解的,但是加上了这个注解生成的文档中就会带着注解了。 @Documented 注释只是用来生成文档的,不重要
@Inherited(极少)
/*** Indicates that an annotation type is automatically inherited. If* an Inherited meta-annotation is present on an annotation type* declaration, and the user queries the annotation type on a class* declaration, and the class declaration has no annotation for this type,* then the class's superclass will automatically be queried for the* annotation type. This process will be repeated until an annotation for this* type is found, or the top of the class hierarchy (Object)* is reached. If no superclass has an annotation for this type, then* the query will indicate that the class in question has no such annotation.** <p>Note that this meta-annotation type has no effect if the annotated* type is used to annotate anything other than a class. Note also* that this meta-annotation only causes annotations to be inherited* from superclasses; annotations on implemented interfaces have no* effect.** @author Joshua Bloch* @since 1.5* @jls 9.6.3.3 @Inherited*/@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Inherited {}
官方文档注释:
@Inherited 官方注释
被它修饰的Annotation将具有继承性。如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解。
自动装配原理
自动配置好Tomcat
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><version>2.6.6</version><scope>compile</scope></dependency>
自动配置好SpringMVC
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.18</version><scope>compile</scope></dependency>
自动配置好Web常见功能:

查看IOC容器组件


- 默认的包结构(约定大于配置)

PS:可以扩大自动扫包的扩大范围
- 各种配置拥有默认值
- 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
- 按需加载所有自动配置项
- 非常多的starter
- 引入了哪些场景这个场景的自动配置才会开启
- SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure
组件添加
@Configuration
- 配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
- 配置类本身也是组件
- proxyBeanMethods:代理bean的方法
- Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
- Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
- 组件依赖必须使用Full模式默认。其他默认是否Lite模式


自动配置原理
引导加载自动配置类
@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interface SpringBootApplication{}
1、@SpringBootConfiguration
2、@ComponentScan
3、@EnableAutoConfiguration

@AutoConfigurationPackage

@Import(AutoConfigurationImportSelector.class)


按需开启自动配置项
修改默认配置
给容器中加入了文件上传解析器:传入的名称不叫multipartResolver,通过multipartResolver方法给它返回正确的名称
@Bean@ConditionalOnBean(MultipartResolver.class) //容器中有这个类型组件// 容器中没有这个名字 multipartResolver 的组件@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)public MultipartResolver multipartResolver(MultipartResolver resolver) {//给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。//SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范// Detect if the user has created a MultipartResolver but named it incorrectlyreturn resolver;}
