2.4 Spring Boot应用注解@Spring BootApplication
我们在上面看到在Spring Boot入口类上面添加了注解@Spring BootApplication,这个注解的定义如下:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Spring BootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExclu deFilter.class) }) public @interface Spring BootApplication {...}
@Spring BootApplication注解实际上封装了以下三个注解:
❑@Spring BootConfiguration:配置类注解。
❑@EnableAutoConfiguration:启用自动配置注解。
❑@ComponentScan:组件扫描注解。
下面我们分别来介绍。
2.4.1 Spring Boot配置类注解
@SpringBootConfiguration与@Component注解是一样的。@SpringBootConfiguration其实是Spring Boot包装的@Configuration注解:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface Spring BootConfiguration { }
而@Configuration注解使用的又是@Component注解:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { @AliasFor(annotation = Component.class) String value() default ""; }
我们知道,@Component注解的功能是把普通POJO实例化到Spring容器中,相当于配置文件中的<bean id = ""class = ""/>。
在类上添加注解@Configuration,表明这个类代表一个Spring配置文件,与原来XML配置是等效的。只不过现在用Java类加上一个@Configuration注解进行配置了,这种方式与XML相比可以称得上是极简风格了。同时基于注解的配置风格,使得代码的可读性也大大增高了。
Spring容器可以扫描出任何我们添加了@Component注解的类,Bean的注册逻辑在Class-PathScanningCandidateComponentProvider这个类的registerDefaultFilters方法里。
提示
注解(Annotation)是JDK1.5中引入的一个新特性。从Spring2.0以后的版本中,Spring引入了基于注解方式的配置,用于取代XML配置文件,从而极简化了Bean的配置,Spring后来的新版本。在Spring Boot中完全采用基于注解(Spring4.x引入了更加智能的@Condition系列注解,我们将会在后面的章节中详细介绍)的配置,实现“零XML的配置”(当然,同时也支持之前的XML配置文件方式)。
2.4.2 启用自动配置注解
@EnableAutoConfiguration这个注解是Spring Boot的最核心注解。首先我们看它的定义:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration {...}
其中,导入配置类注解@Import标识导入@Configuration标注的配置类。@Import用来整合所有在@Configuration注解中定义的Bean配置。这与我们将多个XML配置文件导入到单个文件的场景一致。@Import注解实现了相同的功能。
使用@EnableAutoConfiguration注解可以启用Spring应用程序上下文的自动配置,Spring Boot会去尝试猜测和配置你可能需要的Bean。自动配置类通常是根据类路径中你定义的Bean来推断可能需要怎样的配置。
例如,如果在你的类路径中有tomcat-embedded.jar这个类库,那么Spring Boot会根据此信息来判断你可能需要一个TomcatServletWebServerFactory(除非你已经定义了你自己的ServletWebServerFactory Bean)。当然我们还可以通过设置exclude或者excludeName变量的值来手动排除你不想要的自动配置。
Spring Boot默认扫描的包路径是入口类Demo0HelloWorldApplication所在的根包中,及其所有的子包。通常,Spring Boot自动配置Bean是根据Conditional Bean(条件Bean)中注解的类信息来推断的。例如@ConditionalOnClass、@ConditionalOnMissingBean注解。关于Spring Boot自动配置的相关内容我们将在后面的章节中详细介绍。
2.4.3 组件扫描注解
组件扫描注解@ComponentScan提供的功能与Spring XML配置文件中的<context:component-scan>元素等价。对应@ComponentScan注解的处理类是ConfigurationClassParser。@ComponentScan告诉Spring去哪个package下面扫描Spring注解。Spring会去自动扫描这些被Spring注解标注的类,并且将其注册到Bean容器中。例如下面的XML配置:
<beans> <context:component-scan base-package="com.easy.SpringBoot" name-generator="com.easy.SpringBoot.MyApp" /> </beans>
对应到Java Config风格如下:
@Configuration @ComponentScan(basePackages = "com.easy.SpringBoot", nameGenerator = MyApp.class)
public class AppConfig { . }
如果你有个类用@Controller注解标识了,但是没有加上@ComponentScan告诉Spring去扫描这个类所在的包,那么该Controller就不会被注册到Spring容器中。
不过,Spring Boot中如果不显式地使用@ComponentScan指明对象扫描的包,那么默认只扫描当前启动类所在的包里的类。
我们可以设置basePackageClasses的值来指定要扫描哪个类所在的包,代码示例如下:
@Spring BootApplication @ComponentScan(basePackageClasses=MyApplication.class) //指定扫描MyApplication //类所在的包 public class MyApplication { public static void main(String[] args){ SpringApplication.run(MyApplication.class, args); } }