003 springboot的启动注解

一 .概述

  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]通过启动注解实现自动配置.

猜你喜欢

转载自www.cnblogs.com/trekxu/p/9452326.html
003