Spring Boot最核心的20個註解

Spring Boot最核心的27個註解,你瞭解多少?

 

導讀

 

Spring Boot方式的項目開發已經逐步成爲Java應用開發領域的主流框架,它不僅可以方便地創建生產級的Spring應用程序,還能輕鬆地通過一些註解配置與目前比較火熱的微服務框架SpringCloud集成。

 

而Spring Boot之所以能夠輕鬆地實現應用的創建及與其他框架快速集成,最核心的原因就在於它極大地簡化了項目的配置,最大化地實現了“約定大於配置”的原則。然而基於Spring Boot雖然極大地方便了開發,但是也很容易讓人“雲裏霧裏”,特別是各種註解很容易讓人“知其然而不知其所以然。

 

所以,要想用好Spring Boot就必須對其提供的各類功能註解有一個全面而清晰地認識和理解。一方面可以提高基於Spring Boot的開發效率,另一方面也是面試中被問及框架原理時所必需要掌握的知識點。在接下來的內容中,小編就帶大家一起來探究下Spring Boot的一些常用註解吧!

 

Spring相關6個註解

 

Spring Boot的有些註解也需要與Spring的註解搭配使用,這裏小編梳理了在項目中與Spring Boot註解配合最爲緊密的6個Spring基礎框架的註解。如👇

 

1、@Configuration

 

從Spring3.0,@Configuration用於定義配置類,可替換xml配置文件,被註解的類內部包含有一個或多個被@Bean註解的方法,這些方法將會被AnnotationConfigApplicationContextAnnotationConfigWebApplicationContext類進行掃描,並用於構建bean定義,初始化Spring容器。

 

@Configuration
public class TaskAutoConfiguration {

    @Bean
    @Profile("biz-electrfence-controller")
    public BizElectrfenceControllerJob bizElectrfenceControllerJob() {
        return new BizElectrfenceControllerJob();
    }

    @Bean
    @Profile("biz-consume-1-datasync")
    public BizBikeElectrFenceTradeSyncJob bizBikeElectrFenceTradeSyncJob() {
        return new BizBikeElectrFenceTradeSyncJob();
    }
}

 

2、@ComponentScan

 

做過web開發的同學一定都有用過@Controller,@Service,@Repository註解,查看其源碼你會發現,他們中有一個共同的註解@Component,沒錯@ComponentScan註解默認就會裝配標識了@Controller,@Service,@Repository,@Component註解的類到spring容器中。

 

@ComponentScan(value = "com.abacus.check.api")
public class CheckApiApplication {
    public static void main(String[] args) {
        SpringApplication.run(CheckApiApplication.class, args);
    }
}

 

@SpringBootApplication註解也包含了@ComponentScan註解,所以在使用中我們也可以通過@SpringBootApplication註解的scanBasePackages屬性進行配置。

 

@SpringBootApplication(scanBasePackages = {"com.abacus.check.api", "com.abacus.check.service"})
public class CheckApiApplication {
    public static void main(String[] args) {
        SpringApplication.run(CheckApiApplication.class, args);
    }
}

 

3、@Conditional

 

@Conditional是Spring4新提供的註解,通過@Conditional註解可以根據代碼中設置的條件裝載不同的bean,在設置條件註解之前,先要把裝載的bean類去實現Condition接口,然後對該實現接口的類設置是否裝載的條件。Spring Boot註解中的@ConditionalOnProperty、@ConditionalOnBean等以@Conditional*開頭的註解,都是通過集成了@Conditional來實現相應功能的。

 

4、@Import

 

通過導入的方式實現把實例加入springIOC容器中。可以在需要時將沒有被Spring容器管理的類(不在@MapperScan裏或者沒有加註解@Configuration,@Component,@Service等)導入至Spring容器中。

1.@EnableXXX內部一般會使用

2.ImportSelector : @Import可以引入org.springframework.context.annotation.ImportSelector實現類。ImportSelector接口定義了一個selectImports(),用於指定需要註冊爲bean的Class名稱。使用@Import引入了一個ImportSelector實現類後,會調用實現類中selectImports方法(入參爲當前類的所有註解信息)獲取返回的Class名稱(類全名)數組,之後在都定義爲bean,注入到容器中。

//類定義
public class Square {}

public class Circular {}

//導入
@Import({Square.class,Circular.class})
@Configuration
public class MainConfig{}

 

5、@ImportResource

 

和@Import類似,區別就是@ImportResource導入的是配置文件。

 

@ImportResource("classpath:spring-redis.xml")      //導入xml配置

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

 

6、@Component

 

@Component是一個元註解,意思是可以註解其他類註解,如@Controller @Service @Repository。帶此註解的類被看作組件,當使用基於註解的配置和類路徑掃描的時候,這些類就會被實例化。其他類級別的註解也可以被認定爲是一種特殊類型的組件,比如@Controller 控制器(注入服務)、@Service服務(注入dao)、@Repository dao(實現dao訪問)。@Component泛指組件,當組件不好歸類的時候,我們可以使用這個註解進行標註,作用就相當於 XML配置,<bean id="" class=""/>。

 

Spring Boot最核心的20個註解

 

說完與Spring Boot密切相關的幾個Spring基礎註解後,下面我們就再一起看看Spring Boot提供的核心註解的內容吧!

 

1、@SpringBootApplication

 

這個註解是Spring Boot最核心的註解,用在 Spring Boot的主類上,標識這是一個 Spring Boot 應用,用來開啓 Spring Boot 的各項能力。實際上這個註解是@Configuration(@SpringBootConfiguration),@EnableAutoConfiguration,@ComponentScan三個註解的組合。由於這些註解一般都是一起使用,所以Spring Boot提供了一個統一的註解@SpringBootApplication。

 

@SpringBootApplication(exclude = {
        MongoAutoConfiguration.class,
        MongoDataAutoConfiguration.class,
        DataSourceAutoConfiguration.class,
        ValidationAutoConfiguration.class,
        MybatisAutoConfiguration.class,
        MailSenderAutoConfiguration.class,
})
public class API {
    public static void main(String[] args) {
        SpringApplication.run(API.class, args);
    }
}

 

2、@EnableAutoConfiguration

 

允許 Spring Boot 自動配置註解,開啓這個註解之後,Spring Boot 就能根據當前類路徑下的包或者類來配置 Spring Bean。

 

如:當前類路徑下有 Mybatis 這個 JAR 包,MybatisAutoConfiguration 註解就能根據相關參數來配置 Mybatis 的各個 Spring Bean。

 

@EnableAutoConfiguration實現的關鍵在於引入了AutoConfigurationImportSelector,其核心邏輯爲selectImports方法,邏輯大致如下:

  • 從配置文件META-INF/spring.factories加載所有可能用到的自動配置類;

  • 去重,並將exclude和excludeName屬性攜帶的類排除;

  • 過濾,將滿足條件(@Conditional)的自動配置類返回;

 

 

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage//導入AutoConfigurationImportSelector的子類@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

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

    String[] excludeName() default {};
}

 

3、@SpringBootConfiguration

 

這個註解就是 @Configuration 註解的變體,只是用來修飾是 Spring Boot 配置而已,或者可利於 Spring Boot 後續的擴展。

 

4、@ConditionalOnBean

 

@ConditionalOnBean(A.class)僅僅在當前上下文中存在A對象時,纔會實例化一個Bean,也就是說只有當A.class 在spring的applicationContext中存在時,這個當前的bean才能夠創建。

 

@Bean
//當前環境上下文存在DefaultMQProducer實例時,才能創建RocketMQProducerLifecycle這個Bean
@ConditionalOnBean(DefaultMQProducer.class)
public RocketMQProducerLifecycle rocketMQLifecycle() {
     return new RocketMQProducerLifecycle();
}

   

5、@ConditionalOnMissingBean

 

組合@Conditional註解,和@ConditionalOnBean註解相反,僅僅在當前上下文中不存在A對象時,纔會實例化一個Bean。

 

  @Bean
  //僅噹噹前環境上下文缺失RocketMQProducer對象時,才允許創建RocketMQProducer Bean對象
  @ConditionalOnMissingBean(RocketMQProducer.class)
  public RocketMQProducer mqProducer() {
      return new RocketMQProducer();
  }

 

6、@ConditionalOnClass

 

組合 @Conditional 註解,可以僅當某些類存在於classpath上時候才創建某個Bean。

 

  @Bean
  //當classpath中存在類HealthIndicator時,才創建HealthIndicator Bean對象
  @ConditionalOnClass(HealthIndicator.class)
  public HealthIndicator rocketMQProducerHealthIndicator(Map<String, DefaultMQProducer> producers) {
      if (producers.size() == 1) {
          return new RocketMQProducerHealthIndicator(producers.values().iterator().next());
      }
  }

 

7、@ConditionalOnMissingClass

 

組合@Conditional註解,和@ConditionalOnMissingClass註解相反,當classpath中沒有指定的 Class纔開啓配置。

 

8、@ConditionalOnWebApplication

 

組合@Conditional 註解,當前項目類型是 WEB 項目纔開啓配置。當前項目有以下 3 種類型:ANY(任何Web項目都匹配)、SERVLET(僅但基礎的Servelet項目纔會匹配)、REACTIVE(只有基於響應的web應用程序才匹配)。

 

9、@ConditionalOnNotWebApplication

 

組合@Conditional註解,和@ConditionalOnWebApplication 註解相反,當前項目類型不是 WEB 項目纔開啓配置。

 

10、@ConditionalOnProperty

 

組合 @Conditional 註解,當指定的屬性有指定的值時纔開啓配置。具體操作是通過其兩個屬性name以及havingValue來實現的,其中name用來從application.properties中讀取某個屬性值,如果該值爲空,則返回false;如果值不爲空,則將該值與havingValue指定的值進行比較,如果一樣則返回true;否則返回false。如果返回值爲false,則該configuration不生效;爲true則生效。

 

 @Bean
 //匹配屬性rocketmq.producer.enabled值是否爲true
 @ConditionalOnProperty(value = "rocketmq.producer.enabled", havingValue = "true", matchIfMissing = true)
 public RocketMQProducer mqProducer() {
     return new RocketMQProducer();
 }

 

11、@ConditionalOnExpression

 

組合 @Conditional 註解,當 SpEL 表達式爲 true 時纔開啓配置。

 

@Configuration
@ConditionalOnExpression("${enabled:false}")
public class BigpipeConfiguration {
    @Bean
    public OrderMessageMonitor orderMessageMonitor(ConfigContext configContext) {
        return new OrderMessageMonitor(configContext);
    }
}

 

12、@ConditionalOnJava

 

組合@Conditional 註解,當運行的 Java JVM 在指定的版本範圍時纔開啓配置。

 

13、@ConditionalOnResource

 

組合 @Conditional 註解,當類路徑下有指定的資源纔開啓配置。

 

@Bean
@ConditionalOnResource(resources="classpath:shiro.ini")
protected Realm iniClasspathRealm(){
  return new Realm();
}

 

14、@ConditionalOnJndi

 

組合 @Conditional 註解,當指定的 JNDI 存在時纔開啓配置。

 

15、@ConditionalOnCloudPlatform

 

組合 @Conditional 註解,當指定的雲平臺激活時纔開啓配置。

 

16、@ConditionalOnSingleCandidate

 

組合 @Conditional 註解,當指定的 class 在容器中只有一個 Bean,或者同時有多個但爲首選時纔開啓配置。

 

17、@ConfigurationProperties

 

Spring Boot可使用註解的方式將自定義的properties文件映射到實體bean中,比如config.properties文件。

 

@Data
@ConfigurationProperties("rocketmq.consumer")
public class RocketMQConsumerProperties extends RocketMQProperties {
    private boolean enabled = true;

    private String consumerGroup;

    private MessageModel messageModel = MessageModel.CLUSTERING;

    private ConsumeFromWhere consumeFromWhere = ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET;

    private int consumeThreadMin = 20;

    private int consumeThreadMax = 64;

    private int consumeConcurrentlyMaxSpan = 2000;

    private int pullThresholdForQueue = 1000;

    private int pullInterval = 0;

    private int consumeMessageBatchMaxSize = 1;

    private int pullBatchSize = 32;
}

 

18、@EnableConfigurationProperties

 

當@EnableConfigurationProperties註解應用到你的@Configuration時,任何被@ConfigurationProperties註解的beans將自動被Environment屬性配置。 這種風格的配置特別適合與SpringApplication的外部YAML配置進行配合使用。

 

@Configuration
@EnableConfigurationProperties({
    RocketMQProducerProperties.class,
    RocketMQConsumerProperties.class,
})
@AutoConfigureOrder
public class RocketMQAutoConfiguration {
    @Value("${spring.application.name}")
    private String applicationName;
}

 

19、@AutoConfigureAfter

 

用在自動配置類上面,表示該自動配置類需要在另外指定的自動配置類配置完之後。

如 Mybatis 的自動配置類,需要在數據源自動配置類之後。

@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration {
}

 

20、@AutoConfigureBefore

 

這個和@AutoConfigureAfter註解使用相反,表示該自動配置類需要在另外指定的自動配置類配置之前。

 

21、@AutoConfigureOrder

 

Spring Boot 1.3.0中有一個新的註解@AutoConfigureOrder,用於確定配置加載的優先級順序。

 

  @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) // 自動配置裏面的最高優先級
  @Configuration
  @ConditionalOnWebApplication // 僅限於web應用
  @Import(BeanPostProcessorsRegistrar.class) // 導入內置容器的設置
  public class EmbeddedServletContainerAutoConfiguration {
      @Configuration
      @ConditionalOnClass({ Servlet.class, Tomcat.class })
      @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
      public static class EmbeddedTomcat {
         // ...
      }

      @Configuration
      @ConditionalOnClass({ Servlet.class, Server.class, Loader.class, WebAppContext.class })
      @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
      public static class EmbeddedJetty {
         // ...
      }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章