@SpringBootApplication注解分析


Spring boot簡介

  • Spring Boot是伴隨着Spring4.0 產生的,是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式進行配置,從而使開發人員不再需要定義樣板化的配置。通過這種方式,Boot致力於在蓬勃發展的快速應用開發領域(rapid application development)成為領導者。
  • Spring Boot讓我們的Spring應用變得更輕量化。比如:你可以僅僅依靠一個Java類來運行Spring引用。你也可以打包你的應用為jar並通過使用java –jar來運行你的Spring Web應用。
  • Spring Boot的主要優點:
    為所有Spring開發者更快的入門
    開箱即用,提供各種默認配置來簡化項目配置
    內嵌式容器簡化web項目
    沒有冗余代碼生成和xml配置的要求
    盡可能的根據項目依賴來自動配置Spring框架。
    提供可以直接在生產環境中使用的功能,如性能指標,應用信息和應用健康檢查。
  • Spring Boot的缺點
    依賴太多,隨便的一個Spring Boot應用都有好幾十M
    缺少服務的注冊和發現等解決方案,可以結合springcloud的組件使用。
    缺少監控集成方案、安全管理方案(有但簡單,滿足不了生產的指標)

首先我們分析的就是入口類Application的啟動注解@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 {
....
}

發現@SpringBootApplication是一個復合注解,包括@ComponentScan,和@SpringBootConfiguration@EnableAutoConfiguration

  • @SpringBootConfiguration繼承自@Configuration,二者功能也一致,標注當前類是配置類,並會將當前類內聲明的一個或多個以@Bean注解標記的方法的實例納入到srping容器中,並且實例名就是方法名。
  • @EnableAutoConfiguration的作用啟動自動的配置,@EnableAutoConfiguration注解的意思就是Springboot根據你添加的jar包來配置你項目的默認配置,比如根據spring-boot-starter-web ,來判斷你的項目是否需要添加了webmvctomcat,就會自動的幫你配置web項目中所需要的默認配置。在下面博客會具體分析這個注解,快速入門的demo實際沒有用到該注解。
  • @ComponentScan,掃描當前包及其子包下被@Component@Controller@Service@Repository注解標記的類並納入到spring容器中進行管理。是以前的<context:component-scan>(以前使用在xml中使用的標簽,用來掃描包配置的平行支持)。所以本demo中的User為何會被spring容器管理。

根據上面的理解,上面的入口類Application,我們可以使用:

package com.zhihao.miao;
import com.zhihao.miao.bean.User;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import java.util.Map;

@ComponentScan
public class Application {

    @Bean
    public Runnable createRunnable(){
        return () -> System.out.println("spring boot is running");
    }

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
        context.getBean(Runnable.class).run();

    }
}

使用@ComponentScan注解代替@SpringBootApplication注解,也可以正常運行程序。原因是@SpringBootApplication中包含@ComponentScan,並且springboot會將入口類看作是一個@SpringBootConfiguration標記的配置類,所以定義在入口類Application中的Runnable也可以納入到容器管理。

SpringBootApplication參數詳解

  • Class<?>[] exclude() default {}:
    根據class來排除,排除特定的類加入spring容器,傳入參數value類型是class類型。
  • String[] excludeName() default {}:
    根據class name來排除,排除特定的類加入spring容器,傳入參數value類型是class的全類名字符串數組。
  • String[] scanBasePackages() default {}:
    指定掃描包,參數是包名的字符串數組。
  • Class<?>[] scanBasePackageClasses() default {}:
    掃描特定的包,參數類似是Class類型數組。
@SpringBootApplication只會掃描@SpringBootApplication注解標記類包下及其子包的類(特定注解標記,比如說@Controller,@Service,@Component,@Configuration和@Bean注解等等)納入到spring容器,如果我們定義的Bean不在@SpringBootApplication注解標記類相同包下及其子包的類,所以需要我們去配置一下掃包路徑。

修改啟動類,@SpringBootApplication(scanBasePackages = "com.xxx.xxx"),指定掃描路徑:

import com.zhihao.miao.beans.Cat;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication(scanBasePackages = "com.xxx.xxx")
public class Application {

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

 

當然使用@SpringBootApplication(scanBasePackageClasses = MyConfig.class),指定scanBasePackageClasses參數的value值是你需要掃描的類也可以,結果一樣,不過如果多個配置類不在當前包及其子包下,則需要指定多個。

exclude或excludeName

在上面的列子的相同包下(com.xxx.xxx)配置的bean,都會納入到spring容器中(@Component),我們知道@SpringBootApplication注解會掃描當前包及其子包,如果我們需要將其排除在spring容器中,如何操作?
可以使用@SpringBootApplication的另外二個參數(exclude或excludeName)

然后修改@SpringBootApplication配置,

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

@SpringBootApplication(exclude = People.class)
public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context =SpringApplication.run(Application.class,args);
        People people = context.getBean(People.class);
        System.out.println(people);
    }
}

 

很明顯啟動報錯。使用@excludeName注解也可以。如下,
@SpringBootApplication(excludeName = {"com.xxx.xxx.People"})

參考文檔:
Springboot1.5.4官方文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM