天天看点

Springboot的核心注解@SpringBootApplication

@SpringBootApplication是Springboot项目最为重要的注解,我们面试的时候经常被问到。其实不管是面试与否,作为一名java开发人员,还是有必要搞清楚springboot的核心注解。

1.关于Springboot项目的启动和自动配置问题

自动配置:根据我们添加的jar包依赖,会自动将一些配置类的bean注册进ioc容器,我们可以需要的地 方使用@autowired或者@resource等注解来使用它。

Spring Boot到底是如何进行自动配置的,都把哪些组件进行了自动配置?

1)Spring Boot应用的启动入口是@SpringBootApplication注解标注类中的main()方法。

2)@SpringBootApplication 标注在某个类上说明这个类是 SpringBoot 的主配置 类, SpringBoot 就应该运行这个类的 main() 方法启动 SpringBoot 应用。

[email protected]

下面,查看@SpringBootApplication内部源码进行分析 ,核心代码具体如下:

@Target(ElementType.TYPE) //注解的适用范围,Type表示注解可以描述在类、接口、注解或枚举中
@Retention(RetentionPolicy.RUNTIME) //表示注解的生命周期,Runtime运行时
@Documented //表示注解可以记录在javadoc中
@Inherited //表示可以被子类继承该注解
//------------------------------------------------
@SpringBootConfiguration  // 标明该类为配置类
@EnableAutoConfiguration  // 启动自动配置功能
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) //注解扫描
public @interface SpringBootApplication {

	
	// 根据class来排除特定的类,使其不能加入spring容器,传入参数value类型是class类型。
	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};

	
	// 根据classname 来排除特定的类,使其不能加入spring容器,传入参数value类型是class的全类名字符串数组
	@AliasFor(annotation = EnableAutoConfiguration.class)
	String[] excludeName() default {};

	// 指定扫描包,参数是包名的字符串数组。
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};

	
	// 扫描特定的包,参数类似是Class类型数组。
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class<?>[] scanBasePackageClasses() default {};


	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;

}
           

从上述源码可以看出,@SpringBootApplication注解是一个组合注解,前面 4 个是注解的元注解, 我们主要看后面 3 个注解:@SpringBootConfiguration、@EnableAutoConfiguration、 @ComponentScan三个核心注解,关于这三个核心注解的相关说明具体如下:

[email protected]

@SpringBootConfiguration : SpringBoot 的配置类,标注在某个类上,表示这是一个 SpringBoot 的配置类。 查看@SpringBootConfiguration注解源码,核心代码具体如下。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented

@Configuration//配置类的作用等同于配置文件,配置类也是容器中的一个对象
public @interface SpringBootConfiguration {
     ...
}
           

从上述源码可以看出,@SpringBootConfiguration注解内部有一个核心注解@Configuration,该注解 是Spring框架提供的,表示当前类为一个配置类(XML配置文件的注解表现形式),并可以被组件扫描 器扫描。由此可见,@SpringBootConfiguration注解的作用与@Configuration注解相同,都是标识一 个可以被组件扫描器扫描的配置类,只不过@SpringBootConfiguration是被Spring Boot进行了重新封 装命名而已。

[email protected]

源码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited

@AutoConfigurationPackage // 自动配置包
@Import(AutoConfigurationImportSelector.class) // Spring的底层注解@Import,给容器中导入一个组件;
public @interface EnableAutoConfiguration {

	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};

}
           

1)@AutoConfigurationPackage自动装配包注解,也是一个组合注解,底层也是包含@Import注解。

2)@Import导入注解,也就是给容器导入一个组件。Spring 中有很多以 Enable 开头的注解,其作用就是借助 @Import 来收集并注册特定场景相关的 Bean ,并加载到 IOC 容器。

3)@EnableAutoConfiguration就是借助@Import来收集所有符合自动配置条件的bean定义,并加载到 IoC容器。

其中,@AutoConfigurationPackage和@Import非常重要,下次在讲解。

[email protected]

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
    @AliasFor("basePackages")
    String[] value() default {};

    @AliasFor("value")
    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};
    ...
}
           

注解@ComponentScan就是开始包扫描的注解,我们写业务代码的时候,想注解生效,必须开启包扫描,就是这个注解。其实就是对应的传统springmvc中如下配置:

<context:component-scan base-package="com.alibaba.*"></context:component-scan>