应用框架(Spring-boot 启动过程与工作原理)

入口SpringApplication.run()

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

认识@SpringBootApplication注解

6504d0c810badd4b9e59dcdd33da3c9da02.jpg

是 @Configuration @EnableAutoConfiguration @ComponentScan 三个注解的复合

7afddc9148962154a4d9dd298551d0d176c.jpg

请注意它的返回值:ConfigurableApplicationContext

SpringApplication 构造方法解读

c15a83becc59a2628c0b64a6f35aa29a8bc.jpg

疑问:

1、ApplicationContextInitializer是做什么用的? 请了解它的接口注释、方法注释、实现类有哪些。 2、 ApplicationListener是做什么用的?

SpringApplication.run()实例方法解读

a69054094732c93c14f597107a5887a10dd.jpg

36a66a0e4bc774cc7c2b7e19c0abf71d836.jpg

680f95dc0023d0e76097e9c2e6d98409df7.jpg

环境准备过程解读

e3d0fd15a453fbfefa0e9220de1538e818d.jpg

疑问:

1、参数配置在哪里完成的加载?

在学习参数配置时学习到了一个很重要的类 ConfigFileApplicationListener 。了解到在它里面完成的加载,它又是 在何时被谁调用的呢?

ConfigFileApplicationListener 的类定义

299523ba9642977601070ef7014cef93eee.jpg

它是一个EnvironmentPostProcessor,也是一个ApplicationListener,应该就是通过它们来完成的调用!

    1)实现的EnvironmentPostProcessor方法,在这里完成了加载配置文件的工作。

 183fc209efeece77e4808a64a3990065ee1.jpg

    2) 实现的ApplicationListener方法

d21e2d8d7cc9da6d6e2f2afe508b523f3c3.jpg

问: ApplicationEnvironmentPreparedEvent这个事件会在哪里发布?

dd68a2e16735e05706eead828ee39c097c1.jpg

想要看它的加载执行过程怎么办? 在加载的代码处打个断点就可以看到完整的加载过程了!

a0c4dd735653feb23487342235a8142be86.jpg

ce31b7e9e75aab8cc5da76714034db66111.jpg

ConfigurableApplicationContext 创建与准备过程解读

1.ConfigurableApplicationContext 创建

createApplicationContext()

42e0623c029b52e2923540d4eb82ce614d9.jpg

0def7aa6e5219b72a5bec941a72a48fef1a.jpg

默认的三个常量类名是什么?

73b2784f98014956de5c305e8de53d10db2.jpg

2.准备过程

322714aa7ecaf2e7de495437bba7b432999.jpg

59e9d4bfe80f3605a829c3dd52bb81a4b20.jpg

3.刷新过程

1a4c347c93549477a5eaadd09923a395bb7.jpg

10210bc25040bbfb70451fc1749c1fc93f5.jpg

4.auto configuration的bean定义加载:

问题:1、META-INF/spring.factories中指定的auto configuration Bean定义在哪里完成的加载? 整个过程的代码已看完,没看到这块代码,代码茫茫,如何找到加载它们的代码?

思考:一定会从META-INF/spring.factories中加载,加载的方法是哪个? 前面的代码中已见过从META-INF/spring.factories中加载其他的:

24b7d80d8a92a8d17f8bf33b0135d14ae7d.jpg

那就从这个getSpringFactoriesInstances(...)方法调用中找到一个合适的点,打个断点来看谁会加载自动配置

fd1e87c270508efd30ded87341fe7031fda.jpg

看到,它是调用的SpringFactoriesLoader.loadFactoryNames(type, classLoader));

937fd96dbb78ecab1e36c064782d8fc2889.jpg

在它上打个断点,来看什么时候会加载自动配置的配置类:

316fa920b9495ee4e449e37146ebe69f74f.jpg

得到调用栈:

ab7ba2214984f7252e6a4ef85502accb1af.jpg

从调用栈看到是在进行ConfigurationClassPostProcessor处理阶段

7757aafb69c9646ebdb39b91f9e9279518f.jpg

其实,秘密在@SpringBootApplication复合的 @EnableAutoConfiguration 注解

e41b8fcf023e18bcab57a6a6cd8cae97392.jpg

bb1179fe7a2c56d4ea7cb9e3df20bb2f388.jpg

AutoConfigurationImportSelector 干的这个事

2615ed8bbe07dc3779e976522d4f0ee307a.jpg

重点说明:AutoConfigurationImportSelector 实现了 DeferredImportSelector

DeferredImportSelector 是延迟导入选择器。所谓延迟:在所有指定的、包扫描到的@Configuration类中的 bean定义注册后,才会来处理延迟导入的@Configuration类

1ec5cbce73a07258d334db2b3ba087913c6.jpg

eb20435700364a6661bebd82ad669795beb.jpg

疑问:

1、这里自动配置为什么要以DeferredImportSelector 延迟导入的方式? 答案:让我们自己编程配置的bean提前注册,这样自动配置时的条件判断能发现到我们配置的,就能做到不再配置 自动配置的bean等。比如:如果我们自己配置了数据源bean,则使用我们配置的数据源,不在自动配置数据源。数 据源自动配置的代码中可以看到@ConditionalOnMissingBean({ DataSource.class, XADataSource.class }):

880eb18cf4697c18b21e09b3de6a323ad1f.jpg

5.callRunners(context, applicationArguments) 解读

10554fb61bf2a170ef9d62ce03182733de8.jpg

556fa1064461e0bf8ac13d88d0d448550ef.jpg

66fac0b5c0962d3d82a75c5425344930c29.jpg

ab2835f56781b51414baea02badb6b4c61b.jpg

在代码中我们看到,从applicationContext 获取了所有 ApplicationRunner、CommandLineRunner类型的bean, 并执行了它们的run方法。

疑问

1、ApplicationRunner 是什么?有什么用?

2、CommandLineRunner是什么?有什么用? 两个是同样的用途:当ApplicationContext刷新好后,来执行你的应用逻辑。

示例:

93859faf811ead73a2f621b3e678720c14d.jpg

除此之外,你还有什么方式来执行应用逻辑吗?

0650d7ab336ed77b69e51b83452f056874e.jpg

6.Tomcat是如何跑起来的?

从创建ApplicationContext处开始

f632b34e74dd62d6824956f11a20bf82ad6.jpg

0b661e119236d7d03599af5a008c1a4a719.jpg

e416d08c33ea984323b9a1857801a2bdc2a.jpg

看AnnotationConfigServletWebServerApplicationContext类

72c93969b0dcf7d12ae0bb930b70222cae2.jpg

看它的父类ServletWebServerApplicationContext

796f383d224ac9018985ecbd849c5492606.jpg

355b8005dca01c1adb13242180302965aa0.jpg

WebServer的创建过程:

5738077839aa9a9b65f9154fb4b8cd24520.jpg

onRefresh()方法是AbstractApplicationContext中定义的供子类实现的空模板方法,在refresh()方法中被调用。

c57746621d941489fb3c0535c9644560996.jpg

看它里面的getWebServerFactory():从容器中找ServletWebServerFactory类型的Bean,只能有一个。

2799e2ea29b4271c3fd7cfa71fff669d7ac.jpg

1021d2cbcbe4eb13870b40e9441c5912267.jpg

再看通过factory.getWebServer()得到WebServer,先看接口定义:

fa27a78c0266af7ad3e2b819d744cdbd8c9.jpg

在ServletWebServerApplicationContext中可以看到做这个start动作的方法:

419ca427c7e3e9f3ae5ad3b187a5b0dc083.jpg

TomcatServletWebServerFactory中的实现:

fc817bffc459183e3871a5cdaecda7cb2cb.jpg

疑问:TomcatServletWebServerFactory这个Bean哪里配置的? 在spring boot 的自动配置中可以找到

92691be857f1cf8dc98a5dccd2ff60ee222.jpg

看 ServletWebServerFactoryAutoConfiguration

7180fd58ada765e1d10e845653f5f531baf.jpg

86a3e70aedb1245890ad1ae439f257eb19d.jpg

看ServletWebServerFactoryConfiguration.EmbeddedTomcat.class

434c5ed73b9318c6824b13883b460736e79.jpg

看到 @EnableConfigurationProperties(ServerProperties.class)

b9cfb5ec4c7d86610a85859d12ca73c2117.jpg

可以配置哪些服务器参数:

91180558446cf0a48770c8501bc6ae59b6e.jpg

046f22715ba82405a0eb94c0e76fa2db2d3.jpg

再来看下tomcat可以配置什么参数

21f40aae502a9546a133ae04aaede445f30.jpg

参数配置示例: application.yml

67a6bb2660b977cdfc40fdc300e7f19bf2a.jpg

7.spring boot web 中集成 Servlet api

1、使用 Servlet Filter 有两种方式

方式一 servelt3.0 注解 + @ServletComponentScan

e81d627bff5964f536fed025964a5cf080e.jpg

方式二:ServletRegistrationBean和FilterRegistrationBean注册方式

bdb377b765b3d1757c68973219f3630f284.jpg

2、jsp做视图技术

spring boot 不推荐使用jsp。
集成jsp的步骤:
1、引入对应的jar

7a1cee6bc4e4c3ecaf7d475412529d0e86f.jpg

2、创建jsp文件放置目录 src/main下创建 webapp/WEB-INF/jsp/

bba96e3c80b65cb8bca1c6c68ea0af15169.jpg

 

3、在application.yml中配置spring.mvc.view

09aaefbdb71c2db489348ce54ddb7fb846b.jpg

4、编写Controller jsp

b9325aff137eea3b362fb7f384662838e1a.jpg

fbd14525544112063bdf48f56e66c348037.jpg

5、运行、测试

转载于:https://my.oschina.net/u/3728166/blog/3065469

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值