@SpringBootApplication註解分析

首先咱們分析的就是入口類Application的啓動註解@SpringBootApplication,進入源碼:html

複製代碼
@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@EnableAutoConfigurationjava

  • @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,咱們可使用:web

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();
        System.out.println(context.getBean(User.class));
        Map map = (Map) context.getBean("createMap");
        int age = (int) map.get("age");
        System.out.println("age=="+age);

    }
}

使用@ComponentScan註解代替@SpringBootApplication註解,也能夠正常運行程序。緣由是@SpringBootApplication中包含@ComponentScan,而且springboot會將入口類看做是一個@SpringBootConfiguration標記的配置類,因此定義在入口類Application中的Runnable也能夠歸入到容器管理。spring

SpringBootApplication參數詳解


圖片.png
  • Class<?>[] exclude() default {}:
    根據class來排除,排除特定的類加入spring容器,傳入參數value類型是class類型。
  • String[] excludeName() default {}:
    根據class name來排除,排除特定的類加入spring容器,傳入參數value類型是class的全類名字符串數組。
  • String[] scanBasePackages() default {}:
    指定掃描包,參數是包名的字符串數組。
  • Class<?>[] scanBasePackageClasses() default {}:
    掃描特定的包,參數相似是Class類型數組。

看一個demo學會使用這些參數配置
在包下com.zhihao.miao.springboot定義一個啓動應用類(加上@SpringBootApplication註解)數組

package com.zhihao.miao.springboot;


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

@SpringBootApplication
public class Application {

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

在com.zhihao.miao.beans包下定義一個實體類,而且想將其歸入到spring容器中,tomcat

public class Cat {
}
package com.zhihao.miao.beans;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {

    @Bean
    public Cat cat(){
        return new Cat();
    }

}

啓動啓動類,打印結果以下:springboot


 

說明Cat類並無歸入到spring容器中,這個結果也如咱們所想,由於@SpringBootApplication只會掃描@SpringBootApplication註解標記類包下及其子包的類(特定註解標記,好比說@Controller,@Service,@Component,@Configuration和@Bean註解等等)歸入到spring容器,很顯然MyConfig不在@SpringBootApplication註解標記類相同包下及其子包的類,因此須要咱們去配置一下掃包路徑。mvc

修改啓動類,@SpringBootApplication(scanBasePackages = "com.zhihao.miao"),指定掃描路徑:spring-boot

package com.zhihao.miao.springboot;

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.zhihao.miao")
public class Application {

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

啓動並打印:spa


 

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

再看一個列子,
在上面的列子的相同包下(com.zhihao.miao.springboot)配置了People,並將其歸入到spring容器中(@Component),咱們知道@SpringBootApplication註解會掃描當前包及其子包,因此People類會歸入到spring容器中去,咱們須要將其排除在spring容器中,如何操做?
可使用@SpringBootApplication的另外二個參數(exclude或excludeName)

package com.zhihao.miao.springboot;

import org.springframework.stereotype.Component;

@Component
public class People {
}

啓動類,

package com.zhihao.miao.springboot;


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

@SpringBootApplication
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);
    }
}

啓動並打印結果:


 

而後修改@SpringBootApplication配置,

package com.zhihao.miao.springboot;


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.zhihao.miao.springboot.People"})

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

原文地址:https://www.cnblogs.com/duanxz/p/3756364.html

相關文章
相關標籤/搜索