啓動類的@SpringBootApplication探究

spring boot 給容器中註冊組件包括:java

一、包掃描+組件標註註解(@Controller/@Service/@Repository/@Component)【多用於本身寫的類】spring

二、在配置文件中(@Configuration)使用@Bean註解  【多用於導入第三方包裏面的組件,或是須要對組件作其餘特殊操做】數組

三、@Import【快速給容器中導入一個組件】ui

  • @Import(要導入到容器中的組件);容器中就會自動註冊這個組件,id默認是全類名
  • ImportSelector:返回須要導入的組件的全類名數組;
  • ImportBeanDefinationRegistrar:手動註冊bean到容器中

四、使用spring提供的FactoryBean(工廠Bean)code

  • 默認獲取的是工廠bean調用getObject建立的對象
  • 要獲取工廠Bean自己,咱們須要在id前面加一個&  由於在BeanFactory中專門定義了一個符號 &,來區分獲取factoryBean自己和它所建立的對象
/**
	 * Used to dereference a {@link FactoryBean} instance and distinguish it from
	 * beans <i>created</i> by the FactoryBean. For example, if the bean named
	 * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
	 * will return the factory, not the instance returned by the factory.
	 */
	String FACTORY_BEAN_PREFIX = "&";

 

在寫spring boot項目時,發現使用了@SpringBootApplication註解後,全部使用組件標註的類已經註冊進容器中,可是並無看到@ComponentScan註解。閱讀@SpringBootApplication源碼對象

package org.springframework.boot.autoconfigure;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.annotation.AliasFor;


@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 {

	
	@AliasFor(annotation = EnableAutoConfiguration.class, attribute = "exclude")
	Class<?>[] exclude() default {};

	
	@AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")
	String[] excludeName() default {};

	
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};

	
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class<?>[] scanBasePackageClasses() default {};

}

能夠看到 @SpringBootApplication = @SpringBootConfiguration(=@Configuration) + @EnableAutoConfiguration + @ComponentScan,所以能夠進行自動掃描。get

在上述源碼中看到頻繁出現的@AliasFor註解。以下面所示:源碼

@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class<?>[] scanBasePackageClasses() default {};

上述代碼的含義就是:it

使用@SpringBootApplication(scanBasePackageClasses={xxx.class,xxx.class})和使用@ComponentScan(basePackageClasses={xxx.class,xxx.class})是同樣的效果,即在SpringBootApplication中建立了一個scanBasePackageClasses這樣的屬性,爲了讓這個屬性等同於@ComponentScan屬性中的basePackageClasses屬性,因此使用@AliasFor標籤,分別設置了value(即做爲哪一個屬性的別名)和annotation(即做爲哪一個註解)io

相關文章
相關標籤/搜索