一 .概述
sprongboot通过启动注解启动整个springboot的应用,本节,我们就看看这个注解.
二 .启动类
@SpringBootApplication public class SpringbootApplicationStarter { public static void main(String[] args) { SpringApplication.run(SpringbootApplicationStarter.class, args); } }
上面的代码是一个启动类的代码,我们能看到,是什么简单的.
我们需要关注的就是一个@SpringbootApplication和main方法.
下面我们分析一下这个过程.
public static ConfigurableApplicationContext run(Object[] sources, String[] args) { return new SpringApplication(sources).run(args); }
这个run()方法实际的工作就是创建了一个Springboot的应用,其参数就是启动类.
我们看看这个构造方法内部做了什么.
通过追代码,我们在run()方法之中看到了我们熟悉的部分,就是创建IOC容器并刷新容器.
现在我们能够知道,这个main方法其实就是在创建IOC容器.
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { context.setEnvironment(environment); postProcessApplicationContext(context); applyInitializers(context); listeners.contextPrepared(context); if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logStartupProfileInfo(context); } // Add boot specific singleton beans context.getBeanFactory().registerSingleton("springApplicationArguments", applicationArguments); if (printedBanner != null) { context.getBeanFactory().registerSingleton("springBootBanner", printedBanner); } // Load the sources Set<Object> sources = getSources(); Assert.notEmpty(sources, "Sources must not be empty"); load(context, sources.toArray(new Object[sources.size()])); listeners.contextLoaded(context); }
我们看到了一个load()方法,其中source就是我们传入的配置类.
protected void load(ApplicationContext context, Object[] sources) { if (logger.isDebugEnabled()) { logger.debug( "Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); } BeanDefinitionLoader loader = createBeanDefinitionLoader( getBeanDefinitionRegistry(context), sources); if (this.beanNameGenerator != null) { loader.setBeanNameGenerator(this.beanNameGenerator); } if (this.resourceLoader != null) { loader.setResourceLoader(this.resourceLoader); } if (this.environment != null) { loader.setEnvironment(this.environment); } loader.load(); }
我们看到的是,springboot直接将这个配置类加入到了IOC容器之中.
嘿嘿,现在我们可以分析那个注解了.
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication {
我们看到这个注解上面有三个部分的内容:
我们现在看看他们的作用:
@Configuration public @interface SpringBootConfiguration { }
我们发现第一部分其实就在标示这是一个配置类.
第二个注解就是开启了自动配置
第三个注解就是确定了扫包的位置.
现在我们知道了,springboot通过main方法是如何实现自动配置的功能的了.
[1]创建一个IOC容器
[2]通过启动注解实现自动配置.