站内搜索

搜索

手游源码-游戏源码-棋牌源码资源网-亲测源码-游戏搭建-破解游戏-网站源码-qq技术

100金币/天 购买

源码城 这是博客分析和必不可少的过程(一)

23

主题

68

帖子

83

金币

绿钻会员

Rank: 3Rank: 3

积分
262
发表于 2022-3-4 17:00:13 | 显示全部楼层 |阅读模式
引言

上一篇博客我们将源码在本地成功运行了,所以在本篇博客中我们从源码层面分析,在启动的过程中,是如何初始化容器的。我们平常都是将我们的服务部署到中,然后修改一下配置文件,启动就可以对外提供服务了,但是我们对于其中的一些流程并不是非常的了解,例如如何加载的web.xml等。这是我们分析和必不可少的过程。

注释源码地址:

一、代码启动

平常我们不论是还是linux,我们都是通过脚本来启动,这对于我们分析源码不是很友好,所以我们需要通过代码启动,启动代码如下:

1

2

3

4

5

6

7

=new();

.(8080);

//new出各层容器,并且维护各层容器的关系

.("/","/");

.start();

//阻塞监听端口

.().await();

启动代码还是非常非常简单,从代码中我们就可以看出,我们本篇博客主要分析的就是()方法和start()方法,通过这两个方法我们就可以找到容器是在什么时候被初始化的。

二、框架

在我们进行分析上面两个方法之前,我们先总结一下的基础框架,其实从我们非常熟悉的.xml配置文件中就可以知道,就是一系列父子容器组成:

--->-->--->(容器),这就是我们从配置文件中分析出来的几个容器,启动时候就是逐层启动容器。

三、创建容器(())

3.1方法调用流程图



上面的流程图就是,从源码中逐步分析出来的几个重要的方法,这对于我们分析源码非常有帮助。

3.2源码分析

1)通过反射获得监听器

方法路径:org.....(Hosthost,,);

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

(Hosthost,,){

//通过反射获得一个监听器,

//通过反射得到的一定是的一个实现类,进入得到实现类(org....)

=null;

try{

Classclazz=Class.(().());

=()clazz.().();

}catch(e){

//WrapinIAEsincewecan'ttheto

//tothrowthe

thrownewtion(e);

}

(host,,,);

}

2)获得一个容器()

在下面代码中,()方法通过反射加载容器,并且将设置监听,ctx.();

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18



19

20

21

22

23

24

25

26

27

28

29

30

31

32

(Hosthost,,,

){

(host,);

//获得一个容器()

ctx=(host,);

ctx.();

ctx.();

if(bapp){

ctx.(ener());

}

ctx.((,));

//把监听器添加到中去

ctx.();

if(bapp&&()){

//itfrom(ifitfindsone-it'llhaveduperror)

(()).(());

}

if(host==null){

//会逐层创建容器,并维护容器父子关系

().(ctx);

}else{

host.(ctx);

}

ctx;

}

3)维护各层容器

()方法中得到各层容器,并且维护父亲容器关系,其中包括,容器、容器。并且将容器通过().(ctx);调用中的()方法维护在这个map中。

1

2

3

4

5

6

7

8

9

10

11

12

13

Host(){

//将每一层的容器都new出来

=();

if(.().>0){

(Host).()[0];

}

Hosthost=new();

host.();

//维护中的父子容器

().(host);

host;

}

().(host);方法选择调用父类中的方法



1

2

3

4

5

6

7

8

9



10

11

@

void(child){

if(.){

dp=

new(child);

.(dp);

}else{

//这里的child参数是容器

(child);

}

}

()方法的核心代码

1

2

3

4

5

6

7

8

9

10

11

12

void(child){

if(log.())

log.debug("Addchild"+child+""+this);

(){

if(.get(child.())!=null)

thrownewtion(":Childname'"+

child.()+

"'isnot");

child.(this);//MaythrowIAE

.put(child.(),child);

}

四、启动容器(.start())

4.1、方法调用流程图



4.2、源码分析

说明:、、等容器都是继承

所以这里是模板模式的经典应用

1)逐层启动容器

此时的对应的是我们前面创建的

1

2

3

4

5

6

7

8

9

voidstart(){

//防止容器没有创建

();

//获得容器,并且将得到的容器设置到容器中

();

//这里的start的实现是在类中实现

//方法是一个模板方法,在启动流程中非常关键

.start();

}

2)进入start方法



进入中的start方法,其中核心方法是。



从上面我们知道现在我们调用的是容器的()方法,所以我们这里选择的是



方法路径:org...core..()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

void(){

(T,null);

(.);

s.start();

//Startour

(){

//启动容器,一个中可以配置多个容器,每个容器都对应这我们的一个服务应用

for(:){

//对应.()

.start();

}

}

}

从上面代码中我们可以看出,启动容器的时候需要启动子容器容器天外神坛源码网,从这里开始就是容器逐层向向内引爆,所以接下来就是开始依次调用各层容器的star方法。在这里就不在赘述。

2)中的()方法核心代码,从这开始启动容器

1

2

3

4

5

6

7

8

9

//Startourchild,ifany

//在的流程中方法中加入的,所以这里需要找出来

//这里找出来的就是容器

[]=();

List>=new();

for(child:){

//通过线程池异步的方式启动线程池开始启动容器,进入new

.add(.(new(child)));

}

new(child))方法开始启动容器

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

class{

child;

(child){

this.child=child;

}

@

Voidcall(){

//开始启动源码城,实际调用.()

child.start();

null;

}

}

.()方法中的核心代码:



1

2

3

4

5

6

7

8

void(type,data){

event=new(this,type,data);

//在方法的第一步中,设置的监听的对象

for(:){

//这里调用的是的()方法

.(event);

}

}

进入到中的()方法



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

void(event){

//thewearewith

try{

=()event.();

}catch(e){

log.error(sm.("e",event.()),e);

;

}

//theeventthathas

if(event.().(.T)){

//完成web.xml的内容解析

();

}elseif(event.().(.)){

();

}elseif(event.().(.)){

//fortools

if(!=null){

.();

}

}elseif(event.().(.)){

();

}elseif(event.().(.)){

init();

}elseif(event.().(.)){

();

}

}

在上面方法中,完成对web.xml的加载和解析,同时加载xml中配置的并且封装成对象。

3)、启动容器源码城,.()中的(())方法

1

2

3

4

5



6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

([]){

//"loadon"thatneedtobe

>map=new();

for(child:){

//这里的就是我们前面封装的

=()child;

int=.();

if(


;

}

key=.();

list=map.get(key);

if(list==null){

list=new();

map.put(key,list);

}

list.add();

}

//Loadthe"loadon"

for(list:map.()){

for(:list){

try{

//通过load方法最终会调用的init方法

.load();

}catch(e){

().error(sm.("..",

(),.()),.(e));

//NOTE:load(athat

//fromtheinit())areNOT

//fatalto

//="true"is

if(()){

false;

}

}

}

}

true;

}

通过load方法最终会调用的init方法。

五、总结

上面内容就是整个是如何调用初始化方法的流程,整个流程小编的理解
【天外神坛】免责声明及帮助
1.重要:如果遇到隐藏内容回复后显示为代码状态,直接刷新一下页面即可解决此问题。
2.本文部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责。
3.若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
4.如果本站有侵犯、不妥之处的资源,请在网站右边客服联系我们。将会第一时间解决!
5.本站所有内容均由互联网收集整理、网友上传,仅供大家参考、学习,不存在任何商业目的与商业用途。
6.本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

老群被封加此新群不迷路。
上个主题 下个主题 快速回复 返回列表 客服中心 搜索 QQ加群
上个主题 下个主题 快速回复 返回列表 客服中心 搜索 QQ加群

QQ|Archiver|小黑屋|天外神坛

湘ICP备2021015333号

Powered by 天外神坛 X3.4 © 2020-2022 天外神坛