@SpringBootApplication
对于SpringBoot项目,最开始遇见的注解肯定是@SpringBootApplication。
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
我们
Ctrl+鼠标左键
点进去之后就可以发现,其实@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 {
...
}
除开元注解,对于@SpringBootApplication注解来说其实往下拆分就是三个主要的注释,分别是
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
再继续往下拆的话也不过多了几个注解。剩下的全是元注解。
其实@SpringBootApplication也可以使用@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三个注解组合的方式来替换掉,效果是差不多的。换句话说就是,这三个注解各自的作用组合起来就是@SpringBootApplication的主要功能。
先简单说明下:
注解@SpringBootApplication标记在某个类上就说明这个类是SpringBoot的主要配置类
,SpringBoot就应该运行这个类的主要方法来启动SpringBoot应用。
同样,用@SpringBootApplication标记了某一个类,就表示这个类提供了SpringBoot应用程序。
接下来拆开分析这注解的作用。
@SpringBootConfiguration
首先是@SpringBootConfiguration。这个注解往下点就能发现,除开元注解,它就是多了@Configuration。再往下也不过是@Component注解。
无论是自己写的配置类也好,配置文件也好,如applicationContext.xml,web.xml,springmvc.xml等。这些都相当于Spring中的配置文件。
配置类也是容器中的一个组件,所以在@Configuration注解上,有注解@Component,这就代表容器也会创建配置类的对象。
而@SpringBootConfiguration注解和@Configuration注解都有一个属性:
boolean proxyBeanMethods() default true;
默认值是true,说明这个类会被代理。(这里的代理是指用CGLIB代理)。看是直接从IOC容器中取得对象,还是不使用代理,每次都生成不一样的对象。
@EnableAutoConfiguration
这个注解告诉SpringBoot开启自动配置功能,这样自动配置才能生效。借助@import注解,扫描并实例化满足条件的自动配置的bean,之后加载到IOC容器中(或者说借助@Import的支持,收集和注册特定场景相关的bean定义。)
帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot,并创建对应配置类的Bean,并把该Bean实体交给IoC容器进行管理。
@AutoConfigurationPackage自动配置包,这个注解的作用是将添加该注解的类所在的package,作为自动配置package进行管理。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
...
}
这个注解里面的
@Import(AutoConfigurationPackages.Registrar.class)
,其中Registrar.class
这个是应该静态内部类,会指定扫描我们项目的哪个包。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}
这里还有个注解
@Import(AutoConfigurationImportSelector.class)
,这个注解最为重要是,使得SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot,创建并使用的IoC容器。
@ComponentScan
@ComponentScan注解说起来可能较为复杂。
但目的是为了自动扫描并加载符合条件的组件(比如@Component和@Repository等)或者bean定义,最终将这些bean定义加载到IOC容器中去 。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
...
}
而其中的属性代表的是过滤排除的规则。
总结
核心注解@SpringBootApplication,由三个注解组成,分别是@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan。
同时承担了这三个注解的功能,分别是:
- 说明这个类是一个配置类。
- 开启自动配置。
- 组件扫描。
但注解也仅仅是注解,执行过程并不是由注解完成的,而是由启动项
SpringApplication.run(DemoApplication.class, args);
执行SpringApplication.run()方法完成的。