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文件中声明为普通的定义:
    
      
      
    
    
    
    • @Configuration使用@Component进行元注释,因此@Configuration类是组件扫描的候选对象(通常使用Spring XML的元素),因此也可以像任何常规的@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注释组成,类似于在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的元素并行的支持。
    • 可以指定basepackageclass或basePackages(或其别名值)来定义要扫描的特定包。如果没有定义特定的包,则将对声明此注释的类的包进行扫描。
    • 注意,元素有一个注解配置属性;但是,这个注释没有。这是因为在几乎所有使用@ComponentScan的情况下,默认的注释配置处理(例如处理@Autowired和friends)都是假定的。此外,当使用AnnotationConfigApplicationContext时,注释配置处理器总是被注册,这意味着在@ComponentScan级别禁用它们的任何尝试都将被忽略。

你可能感兴趣的