07_@SpringBootApplication详解

@SpringBootApplication详解

Spring Boot项目启动类

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        System.out.println(MyApplication.class.getClassLoader());
        SpringApplication.run(MyApplication.class,args);
    }
}

查看@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{
    ...
}

前四个注解:是元注解,用来修饰当前注解,就像public类的修饰词,没有实际功能,但实际上重要的只有三个Annotation.
指示一个配置类,该类声明一个或多个@Bean方法,并触发自动配置和组件扫描。这是一个方便的注释,相当于声明@Configuration、@EnableAutoConfiguration和@ComponentScan。

  • @SpringBootConfiguration注解,
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
    ...
}
  • 标识类提供Spring引导应用程序@Configuration。可以作为Spring的标准@Configuration注解的替代,以便自动找到配置。应用程序应该只包含一个@SpringBootConfiguration,大多数惯用的Spring引导应用程序将从@SpringBootApplication继承它。

    • @Configuration表示一个类声明一个或多个@Bean方法,并且可以由Spring容器处理,以便在运行时为这些bean生成bean定义和服务请求,例如:
    @Configuration
    public class AppConfig {
    
       @Bean
       public MyBean myBean() {
           // instantiate, configure and return bean ...
       }
    }
    

    引导@ configuration类

    • @Configuration类通常使用AnnotationConfigApplicationContext或其支持web的变体AnnotationConfigWebApplicationContext引导。关于前者的一个简单例子如下:
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.register(AppConfig.class);
    ctx.refresh();
    MyBean myBean = ctx.getBean(MyBean.class);
    // use myBean ...
    
    
    • 作为直接针对注解AnnotationConfigApplicationContext注册@Configuration类的替代方法,@Configuration类可以在Spring XML文件中声明为普通的<bean>定义:
    <beans>
      <context:annotation-config/>
      <bean class="com.acme.AppConfig"/>
    </beans>
    
    
    • @Configuration使用@Component进行元注释,因此@Configuration类是组件扫描的候选对象(通常使用Spring XML的<context:component-scan/>元素),因此也可以像任何常规的@Component一样利用@Autowired/@Inject。特别是,如果一个构造函数存在,自动装配语义将透明地应用于该构造函数:
    @Configuration
    public class AppConfig {
    
       private final SomeBean someBean;
    
       public AppConfig(SomeBean someBean) {
           this.someBean = someBean;
       }
    
       // @Bean definition using "SomeBean"
    
    }
    
    • @Configuration类不仅可以使用组件扫描引导,还可以自己使用@ComponentScan注释配置组件扫描:
    @Configuration
    @ComponentScan("com.acme.app.services")
    public class AppConfig {
       // various @Bean definitions ...
    }
    
    • 可以通过将Springorg.springframework.core.env.Environment注入@Configuration类来查找外部化值例如,使用@Autowired注解
    @Configuration
    public class AppConfig {
    
      @Autowired Environment env;
    
      @Bean
      public MyBean myBean() {
          MyBean myBean = new MyBean();
          myBean.setName(env.getProperty("bean.name"));
          return myBean;
      }
    }
    
    • 通过环境解析的属性位于在一个或多个“属性源”对象中,@Configuration类可以使用@PropertySource注释将属性源贡献给环境对象:
    @Configuration
    @PropertySource("classpath:/com/acme/app.properties")
    public class AppConfig {
    
      @Inject Environment env;
    
      @Bean
      public MyBean myBean() {
          return new MyBean(env.getProperty("bean.name"));
      }
    }
    
    • 外部值可以使用@Value注释注入@Configuration类:
    @Configuration
    @PropertySource("classpath:/com/acme/app.properties")
    public class AppConfig {
    
      @Value("${bean.name}") String beanName;
    
      @Bean
      public MyBean myBean() {
          return new MyBean(beanName);
      }
    }
    
    • @Configuration类可以使用@Import注释组成,类似于<import>在Spring XML中工作的方式。因为@Configuration对象在容器中被管理为Spring bean,所以导入的配置可能被注入——例如,通过构造函数注入:
    @Configuration
    public class DatabaseConfig {
    
       @Bean
       public DataSource dataSource() {
           // instantiate, configure and return DataSource
       }
    }
    
    @Configuration
    @Import(DatabaseConfig.class)
    public class AppConfig {
    
       private final DatabaseConfig dataConfig;
    
       public AppConfig(DatabaseConfig dataConfig) {
           this.dataConfig = dataConfig;
       }
    
       @Bean
       public MyBean myBean() {
           // reference the dataSource() bean method
           return new MyBean(dataConfig.dataSource());
       }
    }
    
    • @Configuration类可能被标记为@Profile注释,以指示只有在给定的概要文件或概要文件处于活动状态时才应该处理它们:
    
    @Profile("development")
    @Configuration
    public class EmbeddedDatabaseConfig {
    
       @Bean
       public DataSource dataSource() {
           // instantiate, configure and return embedded    DataSource
       }
    }
    
    @Profile("production")
    @Configuration
    public class ProductionDatabaseConfig {
    
       @Bean
       public DataSource dataSource() {
           // instantiate, configure and return production DataSource
       }
    }
    
    • 或者,您也可以在@Bean方法级别声明概要条件——例如,对于相同配置类中的其他bean变量:
    
    @Configuration
    public class ProfileDatabaseConfig {
    
       @Bean("dataSource")
       @Profile("development")
       public DataSource embeddedDatabase() { ... }
    
       @Bean("dataSource")
       @Profile("production")
       public DataSource productionDatabase() { ... }
    }
    
    • @Configuration类可以相互嵌套,如下:
    @Configuration
    public class AppConfig {
    
       @Inject DataSource dataSource;
    
       @Bean
       public MyBean myBean() {
           return new MyBean(dataSource);
       }
    
       @Configuration
       static class DatabaseConfig {
           @Bean
           DataSource dataSource() {
               return new EmbeddedDatabaseBuilder().build();
           }
       }
    }
    
    • 默认情况下,@Bean方法将在容器引导时立即实例化。为了避免这种情况,可以将@Configuration与@Lazy注释一起使用,以指示默认情况下,类中声明的所有@Bean方法都是延时初始化的。注意@Lazy也可以用于单个@Bean方法。
  • @EnableAutoConfiguration注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
 ...
}
  • EnableAutoConfiguration
    • 启用Spring应用程序上下文的自动配置,尝试猜测和配置您可能需要的bean。自动配置类通常基于类路径和定义的bean来应用。例如,如果类路径上有tomcat-embedded.jar,则可能需要一个TomcatServletWebServerFactory(除非定义了自己的ServletWebServerFactory bean)。
    • 当使用SpringBootApplication时,上下文的自动配置是自动启用的,因此添加这个注释没有额外的效果。
    • 自动配置试图尽可能地智能化,当您定义更多自己的配置时,它就会后退。您总是可以手动排除()您永远不想应用的任何配置(如果您没有访问这些配置的权限,则使用exclude())。您还可以通过spring.autoconfigure排除属性。在注册了用户定义bean之后,总是会应用自动配置。
    • 使用@EnableAutoConfiguration注释的类包(通常通过@SpringBootApplication)具有特定的意义,通常用作“缺省值”。例如,它将用于扫描@Entity类。通常建议将@EnableAutoConfiguration(如果不使用@SpringBootApplication)放在根包中,以便可以搜索所有子包和类。
    • 自动配置类是常规的Spring配置bean。它们是使用SpringFactoriesLoader机制定位的(针对该类进行键控)。通常,自动配置bean是@条件bean(通常使用@ConditionalOnClass和@ConditionalOnMissingBean注释)。
  • @ComponentScan注解,主要用于组件扫描和自动装配。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
  ...
}
  • ComponentScan
    • 配置组件扫描指令,以便与@Configuration类一起使用。提供与Spring XML的<context:component-scan>元素并行的支持。
    • 可以指定basepackageclass或basePackages(或其别名值)来定义要扫描的特定包。如果没有定义特定的包,则将对声明此注释的类的包进行扫描。
    • 注意,<context:component-scan>元素有一个注解配置属性;但是,这个注释没有。这是因为在几乎所有使用@ComponentScan的情况下,默认的注释配置处理(例如处理@Autowired和friends)都是假定的。此外,当使用AnnotationConfigApplicationContext时,注释配置处理器总是被注册,这意味着在@ComponentScan级别禁用它们的任何尝试都将被忽略。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容