java框架的使用及原理_应用框架(Spring-boot 启动过程与工作原理)

入口SpringApplication.run()

@SpringBootApplication

public class SpringBootStudyConfigApplication

public static void main(String[] args) {

SpringApplication.run(SpringBootStudyConfigApplication.class, args);

}

}

认识@SpringBootApplication注解

cfddb632100af65f51880406f1757861.png

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

d30cb257b91241ab6ee1bac87a3bc284.png

请注意它的返回值:ConfigurableApplicationContext

SpringApplication 构造方法解读

089bb56b4be6580d40a0e2b2205a5963.png

疑问:

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

SpringApplication.run()实例方法解读

3b6ae32f4edf67ab1c2201766ebd3470.png

b5354a02ddceb6ff5d12395c686fbed9.png

e4aaf0b820e6f3ea29bc688f5097c97f.png

环境准备过程解读

d9cf669b15b3530a8b51ce3aaf4d1174.png

疑问:

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

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

ConfigFileApplicationListener 的类定义

5bac45301192b0d24b0fba8029efd02f.png

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

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

3aaab583c055428efcfedc79e95d6aee.png

2) 实现的ApplicationListener方法

2251fb8a656c8be36595e6e12a1da13f.png

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

d831a5a03f0f639b93acfc824c723977.png

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

4e91f7c300de6bb22829f2e2a3b823b5.png

409d5b9be5beff4a50af26a63abffa54.png

ConfigurableApplicationContext 创建与准备过程解读

1.ConfigurableApplicationContext 创建

createApplicationContext()

3b9a9e2332d8dbed6f25cab69d46514d.png

b312b29c2f96e6f41b557855fcb13904.png

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

fbad28627395e3fe77a7a54d62287d44.png

2.准备过程

f6aa22358344b81732f565caf42b1ffb.png

8af78b4f78011bdd56244956261828e7.png

3.刷新过程

a45ab58157843e870be974e2815cde39.png

ce4cf3ed2b7bac1e3af6a59810ff21f4.png

4.auto configuration的bean定义加载:

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

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

2617a24873c24eb154f44e745a2c6f5d.png

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

194e4612e28237615d8fed1e52eb6e7c.png

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

7c92521c60b30f4f193f6f6f6547fd50.png

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

25ab023816556963dc3715b39b209915.png

得到调用栈:

5365685b3629bd9f215e8713f17226e5.png

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

7cad17ad3c9c6ccd773c5c7bfd443773.png

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

dddbc8b98fcf1ba06a5b22745f6af161.png

5876146ef266cb04222dc1f0c73badb3.png

AutoConfigurationImportSelector 干的这个事

45137ee178d84e2f75260d61815af80b.png

重点说明:AutoConfigurationImportSelector 实现了 DeferredImportSelector

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

64b7da9b2fbecb6e6d428d9428961d0e.png

273854538580abbe1cf78d3b92278f2f.png

疑问:

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

6144b81a6988024a08cb3ddfb46f3b1e.png

5.callRunners(context, applicationArguments) 解读

7333612dff524354cfc36afbd6d898bd.png

d9582563951676602ab898c7d5ca72f8.png

2e8fa9cde95d37bb3ff2c5458d484e15.png

61f02eef4ce05e4c62c13ffbab842f0c.png

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

疑问

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

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

示例:

2b77137f84fa79e66de0d3e30beb1c48.png

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

ce3da14a13e1cd49ed032bc452daf838.png

6.Tomcat是如何跑起来的?

从创建ApplicationContext处开始

558610f40c15b99ca151c9ddff35b139.png

c4d811501c10b822a33be3ccf87a53c5.png

7bb7ae8e24af6a7377ee04d86f6cff51.png

看AnnotationConfigServletWebServerApplicationContext类

33f40834e1fb243684a12097dd51ffdd.png

看它的父类ServletWebServerApplicationContext

926c77a2694168828a913c1f60383c96.png

e631323f5fa5b69615d5de15d4fdbffd.png

WebServer的创建过程:

91ae341d1d6a0f6b08bdbfe59a3d1532.png

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

ddffea6de7fc930b759488c53d0e48a7.png

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

ca893a990a4835fdc9034b1a42523769.png

a42bf76a6965e73b299cde056aef6ded.png

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

942434db5ea6105a16193f351a5b876d.png

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

996d6c4a29f1422822027eb3183d5b29.png

TomcatServletWebServerFactory中的实现:

0bb30e1576e0236a94195aff6c6c8439.png

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

e51cdd3fa7e34321704896df7aafe004.png

看 ServletWebServerFactoryAutoConfiguration

8ca6bd5ff108ed9ac7b2f6009a09c0cf.png

aaad29450dd7be4db0bdb786236beabd.png

看ServletWebServerFactoryConfiguration.EmbeddedTomcat.class

c17227cf10b9d71b31cc32430fa69019.png

看到 @EnableConfigurationProperties(ServerProperties.class)

c43008158165aa73212e35457bbf2d63.png

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

847c34bc8e87491545f46d09550289c3.png

6c264abf728fb8eb1094cbff052e6e63.png

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

26de58adf11544e0b6b2d1c018708f3f.png

参数配置示例: application.yml

faebde981a86118cb40521a23b3683ef.png

7.spring boot web 中集成 Servlet api

1、使用 Servlet Filter 有两种方式

方式一 servelt3.0 注解 + @ServletComponentScan

2f5fcdf657954211b010dcef4ef047e1.png

方式二:ServletRegistrationBean和FilterRegistrationBean注册方式

5691a0977b1d5e6d7f11ca382d59539e.png

2、jsp做视图技术

spring boot 不推荐使用jsp。

集成jsp的步骤:

1、引入对应的jar

b2d51d2f77a311467d0d11c5ef84f070.png

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

cede3fef725199a1b89e369b66190ba0.png

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

238ec5660437b2c38823bbc51ebe937b.png

4、编写Controller jsp

f324e4cece6d31952ad24170d131ba19.png

f49e4542dd39ede1750d9b3925024019.png

5、运行、测试

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值