九 springboot关键注解详细说明

@SpringBootApplication

这个注解是加在启动类上的:

package com.example.myapplication;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

源码:

package org.springframework.boot.autoconfigure;

@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Documented
@java.lang.annotation.Inherited
@org.springframework.boot.SpringBootConfiguration
@org.springframework.boot.autoconfigure.EnableAutoConfiguration
@org.springframework.context.annotation.ComponentScan(excludeFilters = {@org.springframework.context.annotation.ComponentScan.Filter(type = org.springframework.context.annotation.FilterType.CUSTOM, classes = {org.springframework.boot.context.TypeExcludeFilter.class}), @org.springframework.context.annotation.ComponentScan.Filter(type = org.springframework.context.annotation.FilterType.CUSTOM, classes = {org.springframework.boot.autoconfigure.AutoConfigurationExcludeFilter.class})})
public @interface SpringBootApplication {
    @org.springframework.core.annotation.AliasFor(annotation = org.springframework.boot.autoconfigure.EnableAutoConfiguration.class, attribute = "exclude")
    java.lang.Class[] exclude() default {};

    @org.springframework.core.annotation.AliasFor(annotation = org.springframework.boot.autoconfigure.EnableAutoConfiguration.class, attribute = "excludeName")
    java.lang.String[] excludeName() default {};

    @org.springframework.core.annotation.AliasFor(annotation = org.springframework.context.annotation.ComponentScan.class, attribute = "basePackages")
    java.lang.String[] scanBasePackages() default {};

    @org.springframework.core.annotation.AliasFor(annotation = org.springframework.context.annotation.ComponentScan.class, attribute = "basePackageClasses")
    java.lang.Class[] scanBasePackageClasses() default {};
}

@SpringBootApplication等同于 @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan 这三个注解:

  • @SpringBootConfiguration: 在springboot项目中替代@Configuration, 等同于原来xml下面的, 在标记了此标签的类的方法标记 @Bean 可以在容器启动的时候调用这个方法注入一个bean, @Bean等同于xml 的 标签。
/**
 * @author: zenghong
 * @Date: 2019/3/14 11:43
 * @Description: restTemplate配置
 */
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder)
    {   //连接时间2s,数据读取时间10s
        return restTemplateBuilder.setConnectTimeout(Duration.ofSeconds(2))
           .setReadTimeout(Duration.ofSeconds(30))
           .build();
    }
}
  • @ComponentScan 这个注解完成的是自动扫描的功能,相当于Spring XML配置文件中的:,可以使用basePackages属性指定要扫描的包,以及扫描的条件。如果不设置的话默认扫描@ComponentScan注解所在类的同级类和同级目录下的所有类,所以对于一个Spring Boot项目,一般会把入口类放在顶层目录中,这样就能够保证源码目录下的所有类都能够被扫描到。
  • @EnableAutoConfiguration : 开启自动配置。源码:
@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

通过@EnableAutoConfiguration,spring会去 META-INF/spring.factories 中去读取默认配置(注意,所有jar包的 META-INF/spring.factories都会被读取,这意味着我们可以自定义扩展)。@Import注解作用是通过导入的方式吧bean加入到springIOC容器中,支持Configuration,ImportSelector,ImportBeanDefinitionRegistrar三种类型,这里使用的ImportSelector。
比如在spring-boot-autoconfigure jar包下的 META-INF/spring.factories 的部分代码如下:

# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer

# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\

这里定义了自动配置的各个实现类,比如 WebMvcAutoConfiguration ,我们去看看源码:

@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
        TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {

    public static final String DEFAULT_PREFIX = "";

    public static final String DEFAULT_SUFFIX = "";

    private static final String[] SERVLET_LOCATIONS = { "/" };

    @Bean
    @ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
    @ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = true)
    public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
        return new OrderedHiddenHttpMethodFilter();
    }

    @Bean
    @ConditionalOnMissingBean(FormContentFilter.class)
    @ConditionalOnProperty(prefix = "spring.mvc.formcontent.filter", name = "enabled", matchIfMissing = true)
    public OrderedFormContentFilter formContentFilter() {
        return new OrderedFormContentFilter();
    }

这个类代码太长,截了上面一部分,重点这是一个@Configuration类,通过@Bean注入类来完成框架配置,其中会有一些默认值, 比如

SERVLET_LOCATIONS = { "/" }

表示当您不配置sevlet的访问路径的时候,默认是根路径。

下一章 十 SpringApplication.run() 做了些啥?

你可能感兴趣的:(九 springboot关键注解详细说明)