mirror of
https://github.com/youthlql/JavaYouth.git
synced 2026-04-21 10:33:41 +00:00
图床更新,请注意查看readme
This commit is contained in:
@@ -92,11 +92,11 @@ public class AppConfig {
|
||||
|
||||
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013185625476.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013185625476.png" />
|
||||
|
||||
根路径是在这里配的,tomcat的配置自己百度下,很简单
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013185659518.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013185659518.png" />
|
||||
|
||||
## Java的SPI机制
|
||||
|
||||
@@ -321,7 +321,7 @@ cn.imlql.mysql.MySQLSaveService
|
||||
|
||||
### WebApplicationInitializer
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013190116630.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013190116630.png" />
|
||||
|
||||
|
||||
|
||||
@@ -342,13 +342,13 @@ public interface ServletContainerInitializer {
|
||||
|
||||
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013190340419.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013190340419.png"/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013192644360.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013192644360.png"/>
|
||||
|
||||
|
||||
|
||||
@@ -469,15 +469,15 @@ ServiceLoader<DataSaveService> load = ServiceLoader.load(WebApplicationInitializ
|
||||
|
||||
下面就是所有实现了WebApplicationInitializer的类
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013193308488.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013193308488.png" />
|
||||
|
||||
接着在最底下的for循环执行所有实现了WebApplicationInitializer的类的onStartup(),然后就走到了我们的AppStarter
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013194526880.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013194526880.png" />
|
||||
|
||||
到这一步,ioc容器都没有创建,我们给refresh()打个断点,看什么时候启动的ioc
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013194649936.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013194649936.png" />
|
||||
|
||||
|
||||
|
||||
@@ -485,7 +485,7 @@ ServiceLoader<DataSaveService> load = ServiceLoader.load(WebApplicationInitializ
|
||||
|
||||
我看的时候debug断点没有看到从AppStarter的哪一步跳到refresh()的。然后我一步一步走的时候发现不是在这个方法里调用的,注意看下面的图,DispatcherServlet已经new完了,但是debug依然没有跳到refresh(),说明不是在new DispatcherServlet()的时候创建的容器
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211016204522610.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211016204522610.png" />
|
||||
|
||||
不过我凭经验猜测Springmvc里最重要的是DispatcherServlet,会不会是DispatcherServlet的那一步启动了IOC,我们开始进行下面的尝试
|
||||
|
||||
@@ -502,7 +502,7 @@ ServiceLoader<DataSaveService> load = ServiceLoader.load(WebApplicationInitializ
|
||||
3. 每次请求调用service处理
|
||||
4. tomcat停止的时候调用destroy进行销毁
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013195139924.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013195139924.png" />
|
||||
|
||||
4. Serlvet是被谁调用开始初始化的属于tomcat的源码,我们这里不研究,我们这里只需要知道,每一个Servlet都会被初始化就可以了。
|
||||
|
||||
@@ -512,7 +512,7 @@ spring-web中有一个叫DispatcherServlet的类,很明显他是一个Servlet
|
||||
|
||||
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013195948793.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211013195948793.png" />
|
||||
|
||||
1. 想要启动IOC容器,只可能是创建DispatcherServlet对象或者调用init()的时候来搞。上面我们也看到了,创建DispatcherServlet对象的时候debug调用栈并没有显示跳到了refresh方法,所以显然不是创建对象的时候
|
||||
2. 那就只有可能是调用init()的时候开始启动的IOC容器
|
||||
@@ -652,13 +652,13 @@ DispatcherServlet没有重写initFrameworkServlet()
|
||||
|
||||
webloc.setParent(springloc)。类似于双亲委派,容器隔离。先看当前容器有没有这个组件,当前容器没有再去父容器找有没有这个组件
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/mvc-context-hierarchy.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/mvc-context-hierarchy.png"/>
|
||||
|
||||
### AbstractAnnotationConfigDispatcherServletInitializer能更快的整合Spring和SpringMVC
|
||||
|
||||
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211016213745753.png" />AbstractAnnotationConfigDispatcherServletInitializer能更快的整合Spring和SpringMVC
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211016213745753.png" />AbstractAnnotationConfigDispatcherServletInitializer能更快的整合Spring和SpringMVC
|
||||
|
||||
> 后面的讲解都用这个测试类
|
||||
|
||||
@@ -811,7 +811,7 @@ public interface ServletContextListener extends EventListener {
|
||||
|
||||
#### SpringServletContainerInitializer#onStartup()
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017171353930.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017171353930.png" />
|
||||
|
||||
|
||||
|
||||
@@ -858,7 +858,7 @@ public interface ServletContextListener extends EventListener {
|
||||
|
||||
#### AbstractDispatcherServletInitializer#onStartup()
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017172450673.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017172450673.png" />
|
||||
|
||||
因为咱们的QuickAppStarter没有onStarup()所以就调用了父类AbstractDispatcherServletInitializer的,没想到AbstractDispatcherServletInitializer也是继续调用父类的
|
||||
|
||||
@@ -875,7 +875,7 @@ public interface ServletContextListener extends EventListener {
|
||||
|
||||
#### AbstractContextLoaderInitializer#onStartup()
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017172942469.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017172942469.png" />
|
||||
|
||||
|
||||
|
||||
@@ -907,7 +907,7 @@ public abstract class AbstractContextLoaderInitializer implements WebApplication
|
||||
}
|
||||
```
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211016214957367.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211016214957367.png"/>
|
||||
|
||||
|
||||
|
||||
@@ -930,7 +930,7 @@ public abstract class AbstractContextLoaderInitializer implements WebApplication
|
||||
}
|
||||
```
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017174011291.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017174011291.png" />
|
||||
|
||||
getRootConfigClasses()正好是咱们QuickAppStarter这个子类重写的,debug F7进入
|
||||
|
||||
@@ -938,19 +938,19 @@ getRootConfigClasses()正好是咱们QuickAppStarter这个子类重写的,debu
|
||||
|
||||
果不其然,调用了QuickAppStarter#getRootConfigClasses()
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017174118178.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017174118178.png"/>
|
||||
|
||||
|
||||
|
||||
继续往下走创建Web容器,这是Spring父容器,因为你看它getRootConfigClasses()获取的是父容器配置
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017174500213.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017174500213.png"/>
|
||||
|
||||
|
||||
|
||||
然后返回
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017174828598.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017174828598.png" />
|
||||
|
||||
|
||||
|
||||
@@ -983,7 +983,7 @@ public class ContextLoaderListener extends ContextLoader implements ServletConte
|
||||
|
||||
接着就继续返回
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017175108566.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017175108566.png"/>
|
||||
|
||||
|
||||
|
||||
@@ -1022,7 +1022,7 @@ public class ContextLoaderListener extends ContextLoader implements ServletConte
|
||||
}
|
||||
```
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017175449110.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017175449110.png" />
|
||||
|
||||
|
||||
|
||||
@@ -1040,25 +1040,25 @@ public class ContextLoaderListener extends ContextLoader implements ServletConte
|
||||
}
|
||||
```
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017175724861.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017175724861.png"/>
|
||||
|
||||
这里又new了一个容器,和上面那个容器一样都没有初始化。这里也是调用咱们QuickAppStarter重写的方法,因为这里调用的是getServletConfigClasses(),所以很明显这里的容器是Web子容器
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017180020098.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017180020098.png" />
|
||||
|
||||
然后就一路往回返,走到这里
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017180356531.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017180356531.png"/>
|
||||
|
||||
继续F7进入
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017180749457.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017180749457.png" />
|
||||
|
||||
这里就是保存咱们上面刚创建的Web子容器,然后再返回
|
||||
|
||||
#### 返回到SpringServletContainerInitializer#onStartup()
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017181428636.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017181428636.png"/>
|
||||
|
||||
1. 这里应用就加载完了,接下来干嘛呢?
|
||||
2. 你往前看看,咱们的Spring容器和Web子容器都是只是创建完了,都还没有初始化,甚至都没有webloc.setParent(springloc)这样产生父子容器的关系
|
||||
@@ -1072,7 +1072,7 @@ public class ContextLoaderListener extends ContextLoader implements ServletConte
|
||||
|
||||
#### ContextLoaderListener#contextInitialized()
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017182550786.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017182550786.png" />
|
||||
|
||||
|
||||
|
||||
@@ -1080,23 +1080,23 @@ public class ContextLoaderListener extends ContextLoader implements ServletConte
|
||||
|
||||
然后真的走到了这里。tomcat里的代码位置是乱的,乱的意思就是比如说上面写的是4766行的调用,但实际上那里是个`}`大括号。也不知道是什么问题,所以我们就大致看下tomcat的代码,不细究。
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017183133699.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017183133699.png" />
|
||||
|
||||
这里的调用还是对的
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017183255872.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017183255872.png" />
|
||||
|
||||
|
||||
|
||||
应该就是类似这样的调用
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017183351172.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017183351172.png" />
|
||||
|
||||
|
||||
|
||||
走的应该是第一个if
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017183536609.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017183536609.png"/>
|
||||
|
||||
|
||||
|
||||
@@ -1104,21 +1104,21 @@ public class ContextLoaderListener extends ContextLoader implements ServletConte
|
||||
|
||||
#### ContextLoader#initWebApplicationContext()
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017183828726.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017183828726.png" />
|
||||
|
||||
|
||||
|
||||
F7进入,这里因为我重新启动了一次,所以你看到根容器是@3661
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017184039846.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017184039846.png" />
|
||||
|
||||
终于要调用refresh了
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017184056048.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017184056048.png" />
|
||||
|
||||
这里直接放行到容器refresh完毕看下父容器
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017184405806.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017184405806.png" />
|
||||
|
||||
父容器只扫描了,springconfig和helloService,我们继续放行看下Web子容器.
|
||||
|
||||
@@ -1130,7 +1130,7 @@ F7进入,这里因为我重新启动了一次,所以你看到根容器是@36
|
||||
|
||||
跳到了这里,为什么会跳到这里呢?记不记得之前我们用DispatcherServlet保存了Web子容器,这里就要调用DispatcherServlet的相关初始化方法
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017185442060.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017185442060.png"/>
|
||||
|
||||
|
||||
|
||||
@@ -1140,7 +1140,7 @@ F7进入,这里因为我重新启动了一次,所以你看到根容器是@36
|
||||
|
||||
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017191309358.png"/>
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017191309358.png"/>
|
||||
|
||||
上面父子容器关系形成了,并且父容器已经refresh完毕
|
||||
|
||||
@@ -1202,11 +1202,11 @@ F7进入,这里因为我重新启动了一次,所以你看到根容器是@36
|
||||
|
||||
#### FrameworkServlet#createWebApplicationContext()
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017191503347.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017191503347.png" />
|
||||
|
||||
再次来到Web子容器的刷新
|
||||
|
||||
<img src="https://npm.elemecdn.com/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017191705766.png" />
|
||||
<img src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_08/image-20211017191705766.png" />
|
||||
|
||||
1. 然后我们看到子容器只有它自己的东西
|
||||
2. 虽然子容器只有controller,但是因为它保存了父容器。所以它是可以拿到HelloService的,也就是我们可以在HelloController里装配HelloService
|
||||
|
||||
Reference in New Issue
Block a user