Spring源码简析(一)

Spring源码简析(一)

Application启动

使用Spring-boot我们可以非常简单的就能搭建一个spring应用,开发人员可以直接通过Main方法启动的SpringApplication来启动Spring-boot

@SpringBootApplication
@EnableAutoConfiguration
public class DemoApplication  extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(DemoApplication .class);
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication .class, args);
    }

}

声明这样一个类,就是一个spring-boot的应用了,直接运行main方法就可以启动spring-boot。
SpringApplication提供了一个静态方法让用户启动框架,

public static ConfigurableApplicationContext run(Object source, String... args) {
    return run(new Object[] { source }, args);
}

注意这里的source参数,我们传入的是我们自定义的类,这个参数的作用就是来帮助spring-boot确定要从哪里来加载bean,这个方法是动长参数,开发人员可以传入多个参数,这个在后续的代码解读中会继续说明。

public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
    return new SpringApplication(sources).run(args);
}

在创建了SpringApplication之后就开始运行应用,其中最重要的部分就是doRun方法

    private ConfigurableApplicationContext doRun(SpringApplicationRunListeners listeners,
            String... args) {
        ConfigurableApplicationContext context;
        // Create and configure the environment
        ConfigurableEnvironment environment = getOrCreateEnvironment();
        configureEnvironment(environment, args);
        listeners.environmentPrepared(environment);
        if (isWebEnvironment(environment) && !this.webEnvironment) {
            environment = convertToStandardEnvironment(environment);
        }
        //打印banner,也就是平时启动时候打印的spring的标识
        if (this.bannerMode != Banner.Mode.OFF) {
            printBanner(environment);
        }

        // Create, load, refresh and run the ApplicationContext
        //创建context,这个也是全局的bean容器
        context = createApplicationContext();
        //设置运行环境
        context.setEnvironment(environment);
        //预处理context,根据当前的环境配置beanNameGenerator和资源加载器
        postProcessApplicationContext(context);
        //加载各个包里/META_INF/spring.factory配置文件,每个包可以根据自己的特性在文件中配置SrpingContextInitializer接口,用来配置contex的一些属性
        applyInitializers(context);
        //
        listeners.contextPrepared(context);
        if (this.logStartupInfo) {
            logStartupInfo(context.getParent() == null);
            logStartupProfileInfo(context);
        }


        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        //向容器中注册一个singleton的bean
        context.getBeanFactory().registerSingleton("springApplicationArguments",
                applicationArguments);

        // 获取资源,这个就是启动Application的时候我们传入的
        Set<Object> sources = getSources();
        // 开始加载资源到容器
        load(context, sources.toArray(new Object[sources.size()]));
        listeners.contextLoaded(context);

        // Refresh the context
        refresh(context);
        if (this.registerShutdownHook) {
            try {
                context.registerShutdownHook();
            }
            catch (AccessControlException ex) {
                // Not allowed in some environments.
            }
        }
        afterRefresh(context, applicationArguments);
        listeners.finished(context, null);
        return context;
    }

这里的入参是一个SpringApplicationRunListeners 类,内部包含了多个SpringBootApplicationRunListener实例,这些类的实例是通过类似spi的方式获取并实例化的,用户可以在自己的工程META_INF/spring.factories中配置,具体方式可以参考spring-boot其他包中的配置方式。这个类主要是用来监听SpringApplication的生命周期用,包括启动,准备环境,创建context,load,finish等等。

经历了准备环境,创建context,load,refresh操作之后,我们的SpringApplication就启动完成了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值