-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
705 lines (439 loc) · 96.6 KB
/
index.html
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Walter's Blog</title>
<meta name="author" content="Walter">
<meta name="description" content="做一个文雅的程序员">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:site_name" content="Walter's Blog"/>
<meta property="og:image" content="undefined"/>
<link href="/favicon.png" rel="icon">
<link rel="stylesheet" href="/css/bootstrap.min.css" media="screen" type="text/css">
<link rel="stylesheet" href="/css/font-awesome.css" media="screen" type="text/css">
<link rel="stylesheet" href="/css/style.css" media="screen" type="text/css">
<link rel="stylesheet" href="/css/highlight.css" media="screen" type="text/css">
<link rel="stylesheet" href="/css/google-fonts.css" media="screen" type="text/css">
<!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<script src="/js/jquery-2.0.3.min.js"></script>
<!-- analytics -->
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "//hm.baidu.com/hm.js?null";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</head>
<body>
<nav id="main-nav" class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<button type="button" class="navbar-header navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Walter's Blog</a>
<div class="collapse navbar-collapse nav-menu">
<ul class="nav navbar-nav">
<li>
<a href="/archives" title="所有文章归档">
<i class="fa fa-archive"></i>归档
</a>
</li>
<li>
<a href="/categories" title="所有文档分类">
<i class="fa fa-folder"></i>分类
</a>
</li>
<li>
<a href="/tags" title="所有文档标签">
<i class="fa fa-tags"></i>标签
</a>
</li>
<li>
<a href="/about" title="About me.">
<i class="fa fa-user"></i>关于
</a>
</li>
</ul>
</div>
</div> <!-- container -->
</nav>
<div class="clearfix"></div>
<div class="container">
<div class="content">
<div class="page-header">
<h1>name:{name} job:{job} life:{life} .format(name='walterlife', job='JAVA Backend Engineer', life='work hard and have fun')</h1>
</div>
<div class="row page">
<div class="col-md-9">
<div class="slogan">
<i class="fa fa-heart"></i>
Welcome
</div>
<div class="mypage">
<!-- title and entry -->
<!-- display as entry -->
<h3 class="title">
<div class="date"> Dec 3 2015 </div>
<div class="article-title"><a href="/2015/12/03/python-mysqldb-execute-use/" >python mysqldb insert时数据带有转义字符处理</a></div>
</h3>
<div class="entry">
<div class="row">
<div class="col-md-12">
<p>今天在使用python编写数据处理的时候,碰到数据中带有转义字符的时候,插入数据错误(数据是通过format拼接的,因此从数据库读取的字符串中的转移字符不能处理)</p>
<p>后来查阅资料,MysqlDB中的execute 可以将数据参数绑定到sql参数列表中(其实之前封装好的mysqlor.py中有该接口实现,只是从来没用过。。。今天才发现该接口的用处)</p>
<p>具体方法如下</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">params = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line">insert_sql = <span class="string">'INSERT INTO {tb} VALUES(%s, %s, %s)'</span>.format(tb=table_name)</span><br><span class="line">mysql_execute(cur, insert_sql, params) <span class="comment"># params为user对应的字段</span></span><br></pre></td></tr></table></figure>
<p>其中 mysql_execute 函数实现如下</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">mysql_execute</span><span class="params">(cursor, sql, param=None, debug=False)</span>:</span></span><br><span class="line"> <span class="string">u'''</span><br><span class="line"> 执行 SQL 语句</span><br><span class="line"> '''</span></span><br><span class="line"> <span class="keyword">if</span> cursor:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> <span class="keyword">if</span> param <span class="keyword">in</span> [<span class="keyword">None</span>, <span class="string">""</span>, <span class="string">''</span>]:</span><br><span class="line"> <span class="keyword">return</span> cursor.execute(sql)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">if</span> isinstance(param, (list, tuple)): param = param</span><br><span class="line"> <span class="keyword">if</span> debug: <span class="keyword">print</span> <span class="string">"cursor.execute(sql, param) parameter, sql: {s}, param: {p}"</span>.format(s=sql, p=param)</span><br><span class="line"> <span class="keyword">return</span> cursor.execute(sql, param)</span><br><span class="line"> <span class="keyword">except</span> IndexError:</span><br><span class="line"> <span class="comment">#except:</span></span><br><span class="line"> <span class="keyword">if</span> debug: <span class="keyword">print</span> <span class="string">"cursor.execute(sql, param) error, sql: {s}, param: {p}"</span>.format(s=sql, p=param)</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">None</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">if</span> debug: <span class="keyword">print</span> <span class="string">"mysql_execute parameter cursor is error."</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">None</span></span><br></pre></td></tr></table></figure>
</div>
</div>
<a type="button" href="/2015/12/03/python-mysqldb-execute-use/#more" class="btn btn-default more">阅读此文</a>
</div>
<!-- display as entry -->
<h3 class="title">
<div class="date"> Oct 21 2015 </div>
<div class="article-title"><a href="/2015/10/21/maven-use-summary/" >maven_use_summary</a></div>
</h3>
<div class="entry">
<div class="row">
<div class="col-md-12">
<h3 id="1-_指定环境进行编译">1. 指定环境进行编译</h3><ul>
<li>在pom.xml 中定义各种 profile </li>
<li><p>在编译的时候指定 -Pprofile_id 即可</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="title">profiles</span>></span></span><br><span class="line"> <span class="tag"><<span class="title">profile</span>></span></span><br><span class="line"> <span class="tag"><<span class="title">id</span>></span>dd<span class="tag"></<span class="title">id</span>></span></span><br><span class="line"> ...</span><br><span class="line"> <span class="tag"></<span class="title">profile</span>></span></span><br><span class="line"><span class="tag"></<span class="title">profiles</span>></span></span><br></pre></td></tr></table></figure>
</li>
<li><p>可用于编译开发,测试,发布不同的版本</p>
</li>
</ul>
<h3 id="2-_去除测试">2. 去除测试</h3><ul>
<li>-Dmaven.test.skip = true 即可</li>
</ul>
<h3 id="3-_指定特定的测试模块进行测试">3. 指定特定的测试模块进行测试</h3><ul>
<li>-Dtest=test_unit_name 即可</li>
</ul>
</div>
</div>
<a type="button" href="/2015/10/21/maven-use-summary/#more" class="btn btn-default more">阅读此文</a>
</div>
<!-- display as entry -->
<h3 class="title">
<div class="date"> Sep 13 2015 </div>
<div class="article-title"><a href="/2015/09/13/netty-server-learn/" >菜鸟学习系列--netty服务器启动流程分析</a></div>
</h3>
<div class="entry">
<div class="row">
<div class="col-md-12">
<p>最近在学习netty网络编程,下面以netty 中 DiscardServer 例子分析其流程</p>
<p>先贴下DiscardServer.java 代码<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DiscardServer</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">int</span> port;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">DiscardServer</span><span class="params">(<span class="keyword">int</span> port)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.port = port;</span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> <span class="keyword">throws</span> InterruptedException </span>{</span><br><span class="line"> EventLoopGroup bossGroup = <span class="keyword">new</span> NioEventLoopGroup();</span><br><span class="line"> EventLoopGroup workerGroup = <span class="keyword">new</span> NioEventLoopGroup();</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> ServerBootstrap b = <span class="keyword">new</span> ServerBootstrap(); <span class="comment">// 1</span></span><br><span class="line"> b.group(bossGroup, workerGroup) <span class="comment">// 2</span></span><br><span class="line"> .channel(NioServerSocketChannel.class) <span class="comment">// 3</span></span><br><span class="line"> .childHandler(<span class="keyword">new</span> ChannelInitializer<SocketChannel>() { <span class="comment">// 4</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">initChannel</span><span class="params">(SocketChannel ch)</span> </span>{</span><br><span class="line"> ch.pipeline().addLast(<span class="keyword">new</span> DiscardServerHandler());</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> .option(ChannelOption.SO_BACKLOG, <span class="number">128</span>) <span class="comment">// 5</span></span><br><span class="line"> .childOption(ChannelOption.SO_KEEPALIVE, <span class="keyword">true</span>); <span class="comment">// 6</span></span><br><span class="line"> ChannelFuture f = b.bind(port).sync(); <span class="comment">// 7 bind 8 sync</span></span><br><span class="line"></span><br><span class="line"> f.channel().closeFuture().sync(); <span class="comment">// 9</span></span><br><span class="line"> } <span class="keyword">finally</span> { </span><br><span class="line"> workerGroup.shutdownGracefully(); <span class="comment">// 10</span></span><br><span class="line"> bossGroup.shutdownGracefully();</span><br><span class="line"> }</span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>消息处理类 DiscardServerHandler.java 代码<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DiscardServerHandler</span> <span class="keyword">extends</span> <span class="title">ChannelHandlerAdapter</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> Logger logger = Logger.getLogger(DiscardServerHandler.class);</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">channelRead</span><span class="params">(ChannelHandlerContext ctx, Object msg)</span> </span>{</span><br><span class="line"> logger.info(<span class="string">"enter"</span>);</span><br><span class="line"> ByteBuf in = (ByteBuf)msg;</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> logger.info(<span class="string">"recv msg "</span> + in.toString(CharsetUtil.US_ASCII));</span><br><span class="line"> } <span class="keyword">finally</span> {</span><br><span class="line"> ((ByteBuf)msg).release();</span><br><span class="line"> }</span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">exceptionCaught</span><span class="params">(ChannelHandlerContext ctx, Throwable cause)</span> </span>{</span><br><span class="line"> cause.printStackTrace();</span><br><span class="line"> ctx.close();</span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>好,现在现从 DiscardServer 的第1步开始分析</p>
<ol>
<li>调用ServerBootstrap 的无参构造函数,实例化对象<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ServerBootstrap b = <span class="keyword">new</span> ServerBootstrap(); </span><br><span class="line"><span class="comment">// 对应源码</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">ServerBootstrap</span><span class="params">()</span> </span>{ } <span class="comment">// 什么也没干</span></span><br></pre></td></tr></table></figure>
</li>
</ol>
<p>其中ServerBootstrap 的继承关系<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public class ServerBootstrap </span><br><span class="line"> public class AbstractBootstrap</span><br><span class="line"> public interface Cloneable</span><br></pre></td></tr></table></figure></p>
<ol>
<li>将父子事件管理器添加至ServerBootstrap中<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">b.group(bossGroup, workerGroup)</span><br></pre></td></tr></table></figure>
</li>
</ol>
<p>ServerBootstrap group 方法代码<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> ServerBootstrap <span class="title">group</span><span class="params">(EventLoopGroup parentGroup, EventLoopGroup childGroup)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>.group(parentGroup); <span class="comment">// 2.1 调用 父类AbstractBootstrap group 方法, 初始化父类事件管理器</span></span><br><span class="line"> <span class="keyword">if</span> (childGroup == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> NullPointerException(<span class="string">"childGroup"</span>);</span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">this</span>.childGroup != <span class="keyword">null</span>) { <span class="comment">// 如果已经存在则抛异常</span></span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">"childGroup set already"</span>);</span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">this</span>.childGroup = childGroup; <span class="comment">// 初始化子类时间管理器</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>; <span class="comment">// 返回对象本身</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>2.1. super.group(parentGroup);<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> B <span class="title">group</span><span class="params">(EventLoopGroup group)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (group == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> NullPointerException(<span class="string">"group"</span>);</span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">this</span>.group != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">"group set already"</span>);</span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">this</span>.group = group;</span><br><span class="line"> <span class="keyword">return</span> (B) <span class="keyword">this</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>流程和ServerBootstrap.group 类似</p>
<ol>
<li>b.channel(NioServerSocketChannel.class)</li>
</ol>
<p>利用反射机制生成 SocketChannel 实例, 调用的是 AbstractBootstrap.channel<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> B <span class="title">channel</span><span class="params">(Class<? extends C> channelClass)</span> </span>{ </span><br><span class="line"> <span class="keyword">if</span> (channelClass == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> NullPointerException(<span class="string">"channelClass"</span>);</span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">return</span> channelFactory(<span class="keyword">new</span> ReflectiveChannelFactory<C>(channelClass)); <span class="comment">// 3.1</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>其中 NioServerSocketChannel 类的继承关系如下<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">NioServerSocketChannel</span> </span><br><span class="line"> <span class="title">public</span> <span class="title">class</span> <span class="title">AbstractNioMessageChannel</span></span><br><span class="line"> <span class="title">public</span> <span class="title">class</span> <span class="title">AbstractNioChannel</span></span><br><span class="line"> <span class="title">public</span> <span class="title">class</span> <span class="title">AbstractChannel</span></span><br><span class="line"> <span class="title">public</span> <span class="title">interface</span> <span class="title">Channel</span></span><br><span class="line"> <span class="title">public</span> <span class="title">interface</span> <span class="title">Comparable</span></span><br><span class="line"> <span class="title">public</span> <span class="title">interface</span> <span class="title">ServerSocketChannel</span></span><br><span class="line"> <span class="title">public</span> <span class="title">interface</span> <span class="title">ServerChannel</span></span><br><span class="line"> <span class="title">public</span> <span class="title">interface</span> <span class="title">Channel</span></span><br><span class="line"> <span class="title">public</span> <span class="title">interface</span> <span class="title">Comparable</span></span></span><br></pre></td></tr></table></figure></p>
<p>3.1. 调用AbstractBootstrap.channelFactory方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> B <span class="title">channelFactory</span><span class="params">(io.netty.channel.ChannelFactory<? extends C> channelFactory)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> channelFactory((ChannelFactory<C>) channelFactory); </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> B <span class="title">channelFactory</span><span class="params">(ChannelFactory<? extends C> channelFactory)</span> </span>{ </span><br><span class="line"> <span class="keyword">if</span> (channelFactory == <span class="keyword">null</span>) { </span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> NullPointerException(<span class="string">"channelFactory"</span>); </span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">this</span>.channelFactory != <span class="keyword">null</span>) { </span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">"channelFactory set already"</span>); </span><br><span class="line"> } </span><br><span class="line"> </span><br><span class="line"> <span class="keyword">this</span>.channelFactory = channelFactory; <span class="comment">// 设置 Channel 生成工厂实例即ReflectiveChannelFactory</span></span><br><span class="line"> <span class="keyword">return</span> (B) <span class="keyword">this</span>; </span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>其中ReflectiveChannelFactory 类的继承关系<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public class ReflectiveChannelFactory </span><br><span class="line"> public interface ChannelFactory // io.netty.channel.ChannelFactory</span><br><span class="line"> public interface ChannelFactory // io.netty.bootstrap.channelFactory</span><br></pre></td></tr></table></figure></p>
<p>ReflectiveChannelFactory 的方法<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">ReflectiveChannelFactory</span><span class="params">(Class<? extends T> clazz)</span> </span>{ </span><br><span class="line"> <span class="keyword">if</span> (clazz == <span class="keyword">null</span>) { </span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> NullPointerException(<span class="string">"clazz"</span>); </span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">this</span>.clazz = clazz; <span class="comment">// 设置自己需要生成的Channel 实例类型</span></span><br><span class="line">} </span><br><span class="line"></span><br><span class="line"><span class="comment">// 工厂方法,后面会讲到其作用</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> T <span class="title">newChannel</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">return</span> clazz.newInstance();</span><br><span class="line"> } <span class="keyword">catch</span> (Throwable t) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> ChannelException(<span class="string">"Unable to create Channel from class "</span> + clazz, t);</span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<ol>
<li>设置childHandler</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">b.childHandler(<span class="keyword">new</span> ChannelInitializer<SocketChannel>() {</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">initChannel</span><span class="params">(SocketChannel ch)</span> </span>{</span><br><span class="line"> ch.pipeline().addLast(<span class="keyword">new</span> DiscardServerHandler()); <span class="comment">// 没来一次请求都放到pipeline 队列尾, 该函数由childHandler 调用</span></span><br><span class="line"> }</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> ServerBootstrap <span class="title">childHandler</span><span class="params">(ChannelHandler childHandler)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (childHandler == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> NullPointerException(<span class="string">"childHandler"</span>);</span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">this</span>.childHandler = childHandler;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>其中ChannelInitializer 的继承关系为<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ChannelInitializer</span></span><br><span class="line"> <span class="title">public</span> <span class="title">class</span> <span class="title">ChannelHandlerAdapter</span> </span><br><span class="line"> <span class="title">public</span> <span class="title">interface</span> <span class="title">ChannelHandler</span> //定义了各种读写就绪接口</span></span><br></pre></td></tr></table></figure></p>
<p>5 6. 都是添加ChannelOption, option由AbstractBootstrap调用,childOption由ServerBootstrap调用</p>
<ol>
<li>ChannelFuture f = b.bind(port).sync();</li>
</ol>
<p>先看 bind 的实现逻辑<br>bind 在AbstractBootstrap 中有5个实现<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> ChannelFuture <span class="title">bind</span><span class="params">()</span> </span>{</span><br><span class="line"><span class="function"><span class="keyword">public</span> ChannelFuture <span class="title">bind</span><span class="params">(<span class="keyword">int</span> inetPort)</span> <span class="comment">// 本文中调用的</span></span><br><span class="line"><span class="keyword">public</span> ChannelFuture <span class="title">bind</span><span class="params">(String inetHost, <span class="keyword">int</span> inetPort)</span> </span><br><span class="line"><span class="keyword">public</span> ChannelFuture <span class="title">bind</span><span class="params">(InetAddress inetHost, <span class="keyword">int</span> inetPort)</span> </span><br><span class="line"><span class="keyword">public</span> ChannelFuture <span class="title">bind</span><span class="params">(SocketAddress localAddress)</span></span></span><br></pre></td></tr></table></figure></p>
<p>最终都调了 doBind方法<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> ChannelFuture <span class="title">doBind</span><span class="params">(<span class="keyword">final</span> SocketAddress localAddress)</span></span></span><br></pre></td></tr></table></figure></p>
<p>现在开始分析doBind 方法逻辑逻辑<br>AbstractBootstrap.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> ChannelFuture <span class="title">doBind</span><span class="params">(<span class="keyword">final</span> SocketAddress localAddress)</span> </span>{</span><br><span class="line"> <span class="keyword">final</span> ChannelFuture regFuture = initAndRegister();</span><br><span class="line"> <span class="keyword">final</span> Channel channel = regFuture.channel();</span><br><span class="line"> <span class="keyword">if</span> (regFuture.cause() != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">return</span> regFuture;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (regFuture.isDone()) {</span><br><span class="line"> <span class="comment">// At this point we know that the registration was complete and successful.</span></span><br><span class="line"> ChannelPromise promise = channel.newPromise();</span><br><span class="line"> doBind0(regFuture, channel, localAddress, promise);</span><br><span class="line"> <span class="keyword">return</span> promise;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">// Registration future is almost always fulfilled already, but just in case it's not.</span></span><br><span class="line"> <span class="keyword">final</span> PendingRegistrationPromise promise = <span class="keyword">new</span> PendingRegistrationPromise(channel);</span><br><span class="line"> regFuture.addListener(<span class="keyword">new</span> ChannelFutureListener() {</span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">operationComplete</span><span class="params">(ChannelFuture future)</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line"> Throwable cause = future.cause();</span><br><span class="line"> <span class="keyword">if</span> (cause != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="comment">// Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an</span></span><br><span class="line"> <span class="comment">// IllegalStateException once we try to access the EventLoop of the Channel.</span></span><br><span class="line"> promise.setFailure(cause);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">// Registration was successful, so set the correct executor to use.</span></span><br><span class="line"> <span class="comment">// See https://github.com/netty/netty/issues/2586</span></span><br><span class="line"> promise.executor = channel.eventLoop();</span><br><span class="line"> }</span><br><span class="line"> doBind0(regFuture, channel, localAddress, promise);</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> <span class="keyword">return</span> promise;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>首先<br>AbstractBootstrap.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">final</span> ChannelFuture regFuture = initAndRegister();</span><br><span class="line"></span><br><span class="line"><span class="comment">// initAndRegister 方法逻辑</span></span><br><span class="line"><span class="function"><span class="keyword">final</span> ChannelFuture <span class="title">initAndRegister</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">// 生成 NioServerSocketChannel 实例(之前channel 方法设定的)</span></span><br><span class="line"> <span class="keyword">final</span> Channel channel = channelFactory().newChannel(); <span class="comment">// 1</span></span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> init(channel); <span class="comment">// 2</span></span><br><span class="line"> } <span class="keyword">catch</span> (Throwable t) {</span><br><span class="line"> channel.unsafe().closeForcibly();</span><br><span class="line"> <span class="comment">// as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> ChannelFuture regFuture = group().register(channel);</span><br><span class="line"> <span class="keyword">if</span> (regFuture.cause() != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">if</span> (channel.isRegistered()) {</span><br><span class="line"> channel.close();</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> channel.unsafe().closeForcibly();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// If we are here and the promise is not failed, it's one of the following cases:</span></span><br><span class="line"> <span class="comment">// 1) If we attempted registration from the event loop, the registration has been completed at this point.</span></span><br><span class="line"> <span class="comment">// i.e. It's safe to attempt bind() or connect() now because the channel has been registered.</span></span><br><span class="line"> <span class="comment">// 2) If we attempted registration from the other thread, the registration request has been successfully</span></span><br><span class="line"> <span class="comment">// added to the event loop's task queue for later execution.</span></span><br><span class="line"> <span class="comment">// i.e. It's safe to attempt bind() or connect() now:</span></span><br><span class="line"> <span class="comment">// because bind() or connect() will be executed *after* the scheduled registration task is executed</span></span><br><span class="line"> <span class="comment">// because register(), bind(), and connect() are all bound to the same thread.</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> regFuture;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>上述代码中 1 中 newInstance 方法进行分析<br>首先调用的是<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">NioServerSocketChannel</span><span class="params">()</span> </span>{ </span><br><span class="line"> <span class="keyword">this</span>(newSocket(DEFAULT_SELECTOR_PROVIDER));</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>其中 DEFAULT_SELECTOR_PROVIDER 定义为<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 这句话的最终结果就是获得java上层Selector Provider</span></span><br><span class="line"><span class="comment">// 据系统的不同,IO复用机制也不一样,比如linux 2.6以上使用时epoll,以下则是select/poll</span></span><br><span class="line"><span class="comment">// 为什么不用jdk自带的呢?或许这样性能会有所提高吧???</span></span><br><span class="line"><span class="comment">// 具体源码在 java/nio/channels/spi/SelectorProvider.java</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();</span><br></pre></td></tr></table></figure></p>
<p>接着newSocket 方法 => openServerSocketChannel[返回ServerSocketChannel] => 调用NioServerSocketChannel(返回ServerSocketChannel channel) 构造函数实例化<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure></p>
<p>上述代码中 2 中 init 方法 源码实现如下<br>ServerBootstrap.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">init</span><span class="params">(Channel channel)</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line"> <span class="comment">// 获取之前设置父类的options</span></span><br><span class="line"> <span class="keyword">final</span> Map<ChannelOption<?>, Object> options = options();</span><br><span class="line"> <span class="keyword">synchronized</span> (options) {</span><br><span class="line"> channel.config().setOptions(options);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">final</span> Map<AttributeKey<?>, Object> attrs = attrs();</span><br><span class="line"> <span class="keyword">synchronized</span> (attrs) {</span><br><span class="line"> <span class="keyword">for</span> (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {</span><br><span class="line"> <span class="annotation">@SuppressWarnings</span>(<span class="string">"unchecked"</span>)</span><br><span class="line"> AttributeKey<Object> key = (AttributeKey<Object>) e.getKey();</span><br><span class="line"> channel.attr(key).set(e.getValue());</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> ChannelPipeline p = channel.pipeline();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">final</span> EventLoopGroup currentChildGroup = childGroup;</span><br><span class="line"> <span class="keyword">final</span> ChannelHandler currentChildHandler = childHandler;</span><br><span class="line"> <span class="keyword">final</span> Entry<ChannelOption<?>, Object>[] currentChildOptions;</span><br><span class="line"> <span class="keyword">final</span> Entry<AttributeKey<?>, Object>[] currentChildAttrs;</span><br><span class="line"> <span class="keyword">synchronized</span> (childOptions) {</span><br><span class="line"> currentChildOptions = childOptions.entrySet().toArray(newOptionArray(childOptions.size()));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">synchronized</span> (childAttrs) {</span><br><span class="line"> currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(childAttrs.size()));</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> p.addLast(<span class="keyword">new</span> ChannelInitializer<Channel>() {</span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">initChannel</span><span class="params">(Channel ch)</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line"> ChannelPipeline pipeline = ch.pipeline();</span><br><span class="line"> ChannelHandler handler = handler();</span><br><span class="line"> <span class="keyword">if</span> (handler != <span class="keyword">null</span>) {</span><br><span class="line"> pipeline.addLast(handler);</span><br><span class="line"> }</span><br><span class="line"> pipeline.addLast(<span class="keyword">new</span> ServerBootstrapAcceptor(</span><br><span class="line"> currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
</div>
</div>
<a type="button" href="/2015/09/13/netty-server-learn/#more" class="btn btn-default more">阅读此文</a>
</div>
<!-- display as entry -->
<h3 class="title">
<div class="date"> Sep 12 2015 </div>
<div class="article-title"><a href="/2015/09/12/java-blocking-queue-learn/" >java-blocking-queue-learn</a></div>
</h3>
<div class="entry">
<div class="row">
<div class="col-md-12">
<p>Java BlockingQueue 接口在 java.util.concurrent中定义,他保证了线程线程间数据共享是安全的。这篇文章将会讲述 BlockingQueue 的使用。</p>
</div>
</div>
<a type="button" href="/2015/09/12/java-blocking-queue-learn/#more" class="btn btn-default more">阅读此文</a>
</div>
<!-- display as entry -->
<h3 class="title">
<div class="date"> Sep 11 2015 </div>
<div class="article-title"><a href="/2015/09/11/java-volatile-keyword-learn/" >java-volatile-keyword-learn</a></div>
</h3>
<div class="entry">
<div class="row">
<div class="col-md-12">
<p>java volatile 变量写的同时会将之前线程内变量写的变量值同时 refresh in main memory</p>
<p>java volatile 变量读的同时,也会将线程内变量的值同时 refresh from main memory</p>
</div>
</div>
<a type="button" href="/2015/09/11/java-volatile-keyword-learn/#more" class="btn btn-default more">阅读此文</a>
</div>
<!-- display as entry -->
<h3 class="title">
<div class="date"> Sep 11 2015 </div>
<div class="article-title"><a href="/2015/09/11/java-concurrency-multithreading-learn/" >Java并发编程学习</a></div>
</h3>
<div class="entry">
<div class="row">
<div class="col-md-12">
<ol>
<li>模型更加复杂</li>
<li>上下文切换消耗资源</li>
</ol>
</div>
</div>
<a type="button" href="/2015/09/11/java-concurrency-multithreading-learn/#more" class="btn btn-default more">阅读此文</a>
</div>
<!-- display as entry -->
<h3 class="title">
<div class="date"> Sep 8 2015 </div>
<div class="article-title"><a href="/2015/09/08/java-io-learning/" >java-io-learning</a></div>
</h3>
<div class="entry">
<div class="row">
<div class="col-md-12">
</div>
</div>
<a type="button" href="/2015/09/08/java-io-learning/#more" class="btn btn-default more">阅读此文</a>
</div>
<!-- display as entry -->
<h3 class="title">
<div class="date"> Sep 7 2015 </div>
<div class="article-title"><a href="/2015/09/07/java-design-pattern-mediator/" >Java设计模式学习之中介者模式</a></div>
</h3>
<div class="entry">
<div class="row">
<div class="col-md-12">
<p>中介者模式是行为型模式的一种,他一般用于系统中不同对象间消息的统一处理,在GoF中这样介绍:</p>
<blockquote>
<p>通过某种封装,将不同对象松耦合,使之可以互相影响,消息可以互相转发,同时也允许不同对象互不依赖</p>
</blockquote>
<p>当某个应用出现很多对象互相影响时,中介者模式就派上用场了。如果对象之间是强耦合的,这样就会导致维护难度大大增大,不易扩展。而中介者模式可以使对象间松耦合。</p>
<p>飞机场广播就是一个很好的例子,提供了不同飞机之间消息转发的一种机制。对于模式来说的话,他一般是作为一个中间路由,就好比游戏服务中gateway服务一样。</p>
<p>系统中互相交流的对象,我们称之为同事(-_-),我们通常用一个接口类或抽象类表示,然后针对不同的同事再实现具体类</p>
<h2 id="Mediator_Interface">Mediator Interface</h2><p>首先我们创建一个 Mediator Interface,定义了中介者是如何工作的</p>
<p>ChatMediator.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.walterlife.dp.MediatorDP;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">CharMediator</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sendMessage</span><span class="params">(String msg, User user)</span></span>;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addUser</span><span class="params">(User user)</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h2 id="Colleague_Interface">Colleague Interface</h2><p>同事间可以互相转发消息,可以将之定义为接口或抽象类,这里我把他定义为抽象类</p>
<p>User.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.walterlife.dp.MediatorDP;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span> </span>{</span><br><span class="line"> CharMediator mediator;</span><br><span class="line"></span><br><span class="line"> String name;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">User</span><span class="params">(CharMediator mediator, String name)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.mediator = mediator;</span><br><span class="line"> <span class="keyword">this</span>.name = name;</span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">sendMessage</span><span class="params">(String msg)</span></span>;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">receive</span><span class="params">(String msg)</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>在每个同事的内部维护着中介者的引用,这样就可以和其他同事间互相交流了</p>
<h2 id="Concrete_Mediator">Concrete Mediator</h2><p>现在开始实现具体的中介者,该中介者内部维护这 Colleagues list,同时提供了同事间交流的逻辑</p>
<p>ChatMediatorImpl.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.walterlife.dp.MediatorDP;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.apache.log4j.Logger;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CharMediatorImpl</span> <span class="keyword">implements</span> <span class="title">CharMediator</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> Logger logger = Logger.getLogger(CharMediatorImpl.class);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> List<User> users = <span class="keyword">new</span> ArrayList<User>();</span><br><span class="line"></span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sendMessage</span><span class="params">(String msg, User user)</span> </span>{</span><br><span class="line"> <span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line"> <span class="keyword">for</span>(User u: users) {</span><br><span class="line"> <span class="keyword">if</span>(u != user) {</span><br><span class="line"> u.receive(msg);</span><br><span class="line"> } </span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addUser</span><span class="params">(User user)</span> </span>{</span><br><span class="line"> <span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line"> <span class="keyword">if</span>(user != <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">if</span>(!users.contains(user)) {</span><br><span class="line"> users.add(user);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> logger.warn(<span class="string">"add user name "</span> + user.getName() + <span class="string">" is already existing!!!"</span>);</span><br><span class="line"> } </span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> logger.warn(<span class="string">"add user param is null!!!"</span>);</span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h2 id="Concrete_Colleague">Concrete Colleague</h2><p>现在我们开始实现具体的Colleagues</p>
<p>UserImpl.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.walterlife.dp.MediatorDP;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.apache.log4j.Logger;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserImpl</span> <span class="keyword">extends</span> <span class="title">User</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> Logger logger = Logger.getLogger(CharMediatorImpl.class);</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">UserImpl</span><span class="params">(CharMediator mediator, String name)</span> </span>{</span><br><span class="line"> <span class="keyword">super</span>(mediator, name);</span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sendMessage</span><span class="params">(String msg)</span> </span>{</span><br><span class="line"> <span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line"> logger.info(<span class="string">"User "</span> + <span class="keyword">this</span>.name + <span class="string">" send msg "</span> + msg + <span class="string">"!!!"</span>);</span><br><span class="line"> mediator.sendMessage(msg, <span class="keyword">this</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">receive</span><span class="params">(String msg)</span> </span>{</span><br><span class="line"> <span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line"> logger.info(<span class="string">"User "</span> + <span class="keyword">this</span>.name + <span class="string">" receive msg "</span> + msg + <span class="string">"!!!"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>在Colleague 进行发消息时,他是通过中介者来发送的,但是他是不知道中介者内部是如何处理的</p>
<h2 id="测试代码">测试代码</h2><p>现在我们开始测试已经实现的中介者模式,主要实现是,先往中介者中添加Colleagues,然后其中一个Colleague 发送消息来测试逻辑的正确性</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">testMediator</span><span class="params">()</span> </span>{</span><br><span class="line"> CharMediatorImpl mediator = <span class="keyword">new</span> CharMediatorImpl();</span><br><span class="line"> UserImpl walter = <span class="keyword">new</span> UserImpl(mediator, <span class="string">"walter"</span>);</span><br><span class="line"> mediator.addUser(walter);</span><br><span class="line"> mediator.addUser(<span class="keyword">new</span> UserImpl(mediator, <span class="string">"ym"</span>));</span><br><span class="line"> mediator.addUser(<span class="keyword">new</span> UserImpl(mediator, <span class="string">"cj"</span>));</span><br><span class="line"> mediator.addUser(<span class="keyword">new</span> UserImpl(mediator, <span class="string">"test"</span>));</span><br><span class="line"></span><br><span class="line"> walter.sendMessage(<span class="string">"Hello World"</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>解释结果<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">08</span> <span class="number">08</span>:<span class="number">27</span>:<span class="number">49</span> INFO com.walterlife.dp.MediatorDP.UserImpl sendMessage:<span class="number">16</span> -> User walter send msg Hello World!!!</span><br><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">08</span> <span class="number">08</span>:<span class="number">27</span>:<span class="number">49</span> INFO com.walterlife.dp.MediatorDP.UserImpl receive:<span class="number">23</span> -> User ym receive msg Hello World!!!</span><br><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">08</span> <span class="number">08</span>:<span class="number">27</span>:<span class="number">49</span> INFO com.walterlife.dp.MediatorDP.UserImpl receive:<span class="number">23</span> -> User cj receive msg Hello World!!!</span><br><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">08</span> <span class="number">08</span>:<span class="number">27</span>:<span class="number">49</span> INFO com.walterlife.dp.MediatorDP.UserImpl receive:<span class="number">23</span> -> User test receive msg Hello World!!!</span><br></pre></td></tr></table></figure></p>
</div>
</div>
<a type="button" href="/2015/09/07/java-design-pattern-mediator/#more" class="btn btn-default more">阅读此文</a>
</div>
<!-- display as entry -->
<h3 class="title">
<div class="date"> Sep 7 2015 </div>
<div class="article-title"><a href="/2015/09/07/java-design-pattern-template-method/" >Java设计模式之模板方法模式</a></div>
</h3>
<div class="entry">
<div class="row">
<div class="col-md-12">
<p>模板方法模式是行为型模式中一种,他通常只需实现一个根方法即可,该方法规定了各个方法的执行顺序。这些方法中可以是各个子类共有的,也可以是每个子类不一样的,该模板方法是父类独有的,一般可以定义为final,可以防止子类进行重写</p>
<p>现在我们以造房子为例子,一般造房子都是以规定的顺序开工的,先打地基,再搭骨架,然后砌墙,最后上玻璃。其中地基是不同房子基本都是一样的,骨架有的可以是木头的,有的可以是砖块的,有的是玻璃,墙也是同样的。这里我们以玻璃房和木头房举例子,这两个子类都继承房子的基类(HouseTemplate),他们的buildPillars 和 buildWalls 方法是不同的,但是他们的建造顺序都是一样的,在HouseTemplate中的buildHouse中实现</p>
<p>其中为了父类中的模板方法不被子类重写,我们把该方法定义为 final 方法</p>
<h2 id="Template_Method_Abstract_Class">Template Method Abstract Class</h2><p>因为父类中有点方法是不需要实现的,模板方法又必须实现的,故将该类定义为 abstract class</p>
<p>HouseTemplate.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.walterlife.dp.TemplateMethodDP;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.apache.log4j.Logger;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">HouseTemplate</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> Logger logger = Logger.getLogger(HouseTemplate.class);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// template method, order is fioxed</span></span><br><span class="line"> <span class="comment">// final so subclasses can not override it</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">void</span> <span class="title">buildHouse</span><span class="params">()</span> </span>{</span><br><span class="line"> buildFoudation();</span><br><span class="line"> buildPillers();</span><br><span class="line"> buildWalls();</span><br><span class="line"> buildWindows();</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildWindows</span><span class="params">()</span> </span>{</span><br><span class="line"> logger.info(<span class="string">"HouseTemplate build windows!!!"</span>);</span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">buildWalls</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">buildPillers</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildFoudation</span><span class="params">()</span> </span>{</span><br><span class="line"> logger.info(<span class="string">"HouseTemplate build foudation!!!"</span>);</span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>buildHouse() 是模板方法,该方法定义了建造房子固定的顺序</p>
<h2 id="Template_Method_Concrete_Classes">Template Method Concrete Classes</h2><p>这里我们只以 木头房和 玻璃房为例</p>
<p>WoodenHouse.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.walterlife.dp.TemplateMethodDP;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.apache.log4j.Logger;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WoodenHouse</span> <span class="keyword">extends</span> <span class="title">HouseTemplate</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> Logger logger = Logger.getLogger(HouseTemplate.class);</span><br><span class="line"></span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildWalls</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line"> logger.info(<span class="string">"build house with wooden walls!!!"</span>); </span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildPillers</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line"> logger.info(<span class="string">"build house with wooden pills!!!"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>GlassHouse.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.walterlife.dp.TemplateMethodDP;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.apache.log4j.Logger;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GlassHouse</span> <span class="keyword">extends</span> <span class="title">HouseTemplate</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> Logger logger = Logger.getLogger(HouseTemplate.class);</span><br><span class="line"></span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildWalls</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line"> logger.info(<span class="string">"build house with glass walls!!!"</span>); </span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="annotation">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">buildPillers</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line"> logger.info(<span class="string">"build house with glass pills!!!"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h2 id="Test_Method">Test Method</h2><p>现在开始测试我们刚刚实现的模板方法模式 代码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">testTemplateMethod</span><span class="params">()</span> </span>{</span><br><span class="line"> HouseTemplate house = <span class="keyword">new</span> WoodenHouse();</span><br><span class="line"> house.buildHouse();</span><br><span class="line"> logger.info(<span class="string">"================================"</span>);</span><br><span class="line"></span><br><span class="line"> house = <span class="keyword">new</span> GlassHouse();</span><br><span class="line"> house.buildHouse();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>输出<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">07</span> <span class="number">22</span>:<span class="number">43</span>:<span class="number">28</span> INFO com.walterlife.dp.TemplateMethodDP.HouseTemplate buildFoudation:<span class="number">27</span> -> HouseTemplate build foudation!!!</span><br><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">07</span> <span class="number">22</span>:<span class="number">43</span>:<span class="number">28</span> INFO com.walterlife.dp.TemplateMethodDP.WoodenHouse buildPillers:<span class="number">18</span> -> build house with wooden pills!!!</span><br><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">07</span> <span class="number">22</span>:<span class="number">43</span>:<span class="number">28</span> INFO com.walterlife.dp.TemplateMethodDP.WoodenHouse buildWalls:<span class="number">12</span> -> build house with wooden walls!!!</span><br><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">07</span> <span class="number">22</span>:<span class="number">43</span>:<span class="number">28</span> INFO com.walterlife.dp.TemplateMethodDP.HouseTemplate buildWindows:<span class="number">19</span> -> HouseTemplate build windows!!!</span><br><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">07</span> <span class="number">22</span>:<span class="number">43</span>:<span class="number">28</span> INFO com.walterlife.dp.App testTemplateMethod:<span class="number">24</span> -> ================================</span><br><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">07</span> <span class="number">22</span>:<span class="number">43</span>:<span class="number">28</span> INFO com.walterlife.dp.TemplateMethodDP.HouseTemplate buildFoudation:<span class="number">27</span> -> HouseTemplate build foudation!!!</span><br><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">07</span> <span class="number">22</span>:<span class="number">43</span>:<span class="number">28</span> INFO com.walterlife.dp.TemplateMethodDP.GlassHouse buildPillers:<span class="number">18</span> -> build house with glass pills!!!</span><br><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">07</span> <span class="number">22</span>:<span class="number">43</span>:<span class="number">28</span> INFO com.walterlife.dp.TemplateMethodDP.GlassHouse buildWalls:<span class="number">12</span> -> build house with glass walls!!!</span><br><span class="line"><span class="number">2015</span>-<span class="number">09</span>-<span class="number">07</span> <span class="number">22</span>:<span class="number">43</span>:<span class="number">28</span> INFO com.walterlife.dp.TemplateMethodDP.HouseTemplate buildWindows:<span class="number">19</span> -> HouseTemplate build windows!!!</span><br></pre></td></tr></table></figure></p>
</div>
</div>
<a type="button" href="/2015/09/07/java-design-pattern-template-method/#more" class="btn btn-default more">阅读此文</a>
</div>
<!-- display as entry -->
<h3 class="title">
<div class="date"> Sep 6 2015 </div>
<div class="article-title"><a href="/2015/09/06/java-design-pattern-proxy/" >Java设计模式学习之代理模式</a></div>
</h3>
<div class="entry">
<div class="row">
<div class="col-md-12">
<p>代理模式是结构型模式中的一种,在GOF中有如下介绍</p>
<blockquote>
<p>为另外一个对象提供代理,以便可以访问该对象</p>
</blockquote>
<p>当我们需要实现控制访问的功能,就可以使用该模式</p>
<p>就拿linux系统命令而言,并不是所有的命令普通用户都可以执行的,这里linux系统的用户的权限管理模块就是一种代理,当用户想要执行命令时,最终都会代理到该模块,然后执行相应的命令</p>
<p>我们就简单的以执行命令为例子来实现代理模式</p>
<p>首先从接口开始编写代码</p>
<h2 id="接口类">接口类</h2><p>CommandExecutor.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.walterlife.dp.ProxyDP;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">CommandExecuter</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">runCommand</span><span class="params">(String cmd)</span> <span class="keyword">throws</span> Exception</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h2 id="接口实现类">接口实现类</h2><p>CommandExecutorImp.java<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.walterlife.dp.ProxyDP;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.apache.log4j.Logger;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CommandExecuterImpl</span> <span class="keyword">implements</span> <span class="title">CommandExecuter</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> Logger logger = Logger.getLogger(CommandExecuter.class);</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">runCommand</span><span class="params">(String cmd)</span> <span class="keyword">throws</span> IOException </span>{</span><br><span class="line"> Runtime.getRuntime().exec(cmd);</span><br><span class="line"> logger.info(<span class="string">"CommandExecuter run cmd: "</span> + cmd); </span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
</div>
</div>
<a type="button" href="/2015/09/06/java-design-pattern-proxy/#more" class="btn btn-default more">阅读此文</a>
</div>
</div>
<!-- pagination -->
<div>
<center>
<div class="pagination">
<ul class="pagination">
<li class="prev disabled"><a><i class="fa fa-arrow-circle-o-left"></i>上一页</a></li>
<li><a href="/"><i class="fa fa-home"></i>Home</a></li>
<li class="next"> <a href="/page/2/" class="alignright next">下一页<i class="fa fa-arrow-circle-o-right"></i></a> </li>
</ul>
</div>
</center>
</div>
</div> <!-- col-md-9 -->
<div class="col-md-3">
<div id="sidebar">
<div class="form-group has-success has-feedback">
<form class="site-search-form">
<input type="text" id="st-search-input" name="q" results="0" placeholder="搜索" class="st-search-input st-default-search-input form-control" />
</form>
</div>
<div class="widget">
<h4>分类</h4>
<ul class="tag_box inline list-unstyled">
<li><a href="/categories/code/">code<span>1</span></a></li>
<li><a href="/categories/cpp/">cpp<span>2</span></a></li>
<li><a href="/categories/db/">db<span>1</span></a></li>
<li><a href="/categories/java/">java<span>20</span></a></li>
<li><a href="/categories/python/">python<span>1</span></a></li>
<li><a href="/categories/summary/">summary<span>7</span></a></li>
<li><a href="/categories/tools/">tools<span>2</span></a></li>
</ul>
</div>
<div class="widget">
<h4>标签云</h4>
<ul class="tag_box inline list-unstyled">
<li><a href="/tags/mongodb/">mongodb<span>1</span></a></li>
<li><a href="/tags/cpp/">cpp<span>2</span></a></li>
<li><a href="/tags/linux/">linux<span>2</span></a></li>
<li><a href="/tags/java/">java<span>2</span></a></li>
<li><a href="/tags/work/">work<span>1</span></a></li>
<li><a href="/tags/python/">python<span>1</span></a></li>
<li><a href="/tags/core-java/">core-java<span>6</span></a></li>
<li><a href="/tags/java-core/">java-core<span>2</span></a></li>
<li><a href="/tags/netty/">netty<span>1</span></a></li>
<li><a href="/tags/spring/">spring<span>2</span></a></li>
<li><a href="/tags/bash/">bash<span>1</span></a></li>
<li><a href="/tags/interview/">interview<span>3</span></a></li>
<li><a href="/tags/java-concurrent/">java-concurrent<span>1</span></a></li>
<li><a href="/tags/struts2/">struts2<span>1</span></a></li>
<li><a href="/tags/maven/">maven<span>2</span></a></li>
<li><a href="/tags/design-pattern/">design-pattern<span>13</span></a></li>
<li><a href="/tags/servlet/">servlet<span>1</span></a></li>
</ul>
</div>
<div class="widget">
<h4>最新文章</h4>
<ul class="entry list-unstyled">
<li>
<a href="/2015/12/03/python-mysqldb-execute-use/" ><i class="fa fa-file-o"></i>python mysqldb insert时数据带有转...</a>
</li>
<li>
<a href="/2015/10/21/maven-use-summary/" ><i class="fa fa-file-o"></i>maven_use_summary...</a>
</li>
<li>
<a href="/2015/09/13/netty-server-learn/" ><i class="fa fa-file-o"></i>菜鸟学习系列--netty服务器启动流程分析...</a>
</li>
<li>
<a href="/2015/09/12/java-blocking-queue-learn/" ><i class="fa fa-file-o"></i>java-blocking-queue-learn...</a>
</li>
<li>
<a href="/2015/09/11/java-volatile-keyword-learn/" ><i class="fa fa-file-o"></i>java-volatile-keyword-learn...</a>
</li>
</ul>
</div>
<div class="widget">
<h4>链接</h4>
<ul class="blogroll list-unstyled">
<li><i class=""></i><a href="https://github.com/wzpan/freemind/" title="Freemind's Github repository." target="_blank"]);">Freemind</a></li>
<li><i class=""></i><a href="http://www.github.com/walterlife" title="My Github account." target="_blank"]);">Github</a></li>
<li><i class=""></i><a href="http://www.zhihu.com/people/walterlife" title="My zhihu account." target="_blank"]);">知乎</a></li>
<li><i class=""></i><a href="http://book.douban.com/people/walterlife/" title="My douban account." target="_blank"]);">豆瓣</a></li>
</ul>
</div>
</div> <!-- sidebar -->
</div> <!-- col-md-3 -->
</div> <!-- row-fluid -->
</div>
</div>
<div class="container-narrow">
<footer> <p>
© 2015 Walter
with help from <a href="http://hexo.io/" target="_blank">Hexo</a> and <a href="http://getbootstrap.com/" target="_blank">Twitter Bootstrap</a>. Theme by <a href="http://github.com/wzpan/hexo-theme-freemind/">Freemind</a>.
</p> </footer>
</div> <!-- container-narrow -->
<script type="text/javascript">
(function(w,d,t,u,n,s,e){w['SwiftypeObject']=n;w[n]=w[n]||function(){
(w[n].q=w[n].q||[]).push(arguments);};s=d.createElement(t);
e=d.getElementsByTagName(t)[0];s.async=1;s.src=u;e.parentNode.insertBefore(s,e);
})(window,document,'script','//s.swiftypecdn.com/install/v2/st.js','_st');
_st('install', 'ZP2ZSuHgipSZfRyU8uTR','2.0.0');
</script>
<a id="gotop" href="#">
<span>▲</span>
</a>
<script src="/js/jquery.imagesloaded.min.js"></script>
<script src="/js/gallery.js"></script>
<script src="/js/bootstrap.min.js"></script>
<script src="/js/main.js"></script>
<script type="text/javascript">
var duoshuoQuery = { short_name: 'walterlife' };
(function() {
var ds = document.createElement('script');
ds.type = 'text/javascript';
ds.async = true;
ds.src = 'http://static.duoshuo.com/embed.js';
ds.charset = 'UTF-8';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ds);
})();
</script>
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css" media="screen" type="text/css">
<script src="/fancybox/jquery.fancybox.pack.js"></script>
<script type="text/javascript">
(function($){
$('.fancybox').fancybox();
})(jQuery);
</script>
</body>
</html>