使用springboot開發web應用是很方便,只須要引入相對應的GAV就能夠使用對應的功能,springboot默認會幫咱們配置好一些經常使用配置。那麼springboot是怎麼作到的呢?這篇文章將一步步跟蹤源碼,查看springboot究竟是如何幫咱們作自動化配置。web
@SpringBootApplication
能夠看到使用@import導入一個開啓自動配置的選擇器spring
@import的做用,官方源碼springboot
* @author Chris Beams * @since 3.0 * @see Configuration * @see ImportSelector * @see ImportResource */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Import { /** * The @{@link Configuration}, {@link ImportSelector} and/or * {@link ImportBeanDefinitionRegistrar} classes to import. */ Class<?>[] value(); }
導入@Configuration註解的配置類
導入ImportSelector的實現類
導入ImportBeanDefinitionRegistrar的實現類app
接着看導入的這個選擇器(@EnableAutoConfigurationImportSelector.class)url
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; }
這裏方法調用了兩個核心方法spa
一、 getSpringFactoriesLoaderFactoryClass(),咱們發現返回的是EnableAutoConfiguration.classcode
二、loadFactoryNames這個方法blog
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) { String factoryClassName = factoryClass.getName(); try { Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); List<String> result = new ArrayList<String>(); while (urls.hasMoreElements()) { URL url = urls.nextElement(); Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); String propertyValue = properties.getProperty(factoryClassName); for (String factoryName : StringUtils.commaDelimitedListToStringArray(propertyValue)) { result.add(factoryName.trim()); } } return result; } catch (IOException ex) { throw new IllegalArgumentException("Unable to load factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex); } }
先獲取factoryClass(EnableAutoConfiguration)的className(org.springframework.boot.autoconfigure.EnableAutoConfiguration),ip
將這個className當作Property的key值,來獲取Value。springboot默認會全局掃描FACTORIES_RESOURCE_LOCATION開發
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
springboot將會加載(org.springframework.boot.autoconfigure.EnableAutoConfiguration)所對應的全部自動配置到spring IOC容器中
以(org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration)爲例。
咱們看到當前自動配置類核心在這幾個註解。
@Configuration @ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class }) @ConditionalOnProperty(prefix = "spring.http.multipart", name = "enabled", matchIfMissing = true) @EnableConfigurationProperties(MultipartProperties.class)
@Configuration spring註解配置類
@ConditionalOnClass 意思是存在某個類,當前配置生效
@ConditionalOnProperty 意思是否存在開啓的spring.http.multipart 的配置,這裏默認開啓,對應的是springboot主配置文件(application)文件中配置項目
@EnableConfigurationProperties 意思是將MultipartProperties類加入spring容器,等價於在MultipartProperties類上加 @Component註解
咱們去看一下MultipartProperties類是幹什麼了?
@ConfigurationProperties(prefix = "spring.http.multipart", ignoreUnknownFields = false) public class MultipartProperties {
@ConfigurationProperties 讀取springboot主配置文件(application.prperties)的配置
因此最後發現只要知足@Conditionalxxxx條件 ,當前自動配置類便可生效。
綜上,若是咱們想知道引入的某個GAV能夠配置哪些屬性,主須要找到對應的xxxAutoConfiguration 查看對應的
@EnableConfigurationProperties(xxxx.class)引入的class便可。