天天看點

使用RelProxy提高Java開發效率

relproxy 旨在通過下列兩種方式提高開發效率:

可以在生産環境下修改使用者代碼,而不需要重新加載整個應用。

提高開發效率,避免花費過多的時間加載應用且對性能不會有影響。

使用RelProxy提高Java開發效率

兩個目标都要求在你的應用中增加一些 relproxy 代碼,注冊成一種典型的監聽、回調模式。這是一種“侵入”的方式。

如果你是一名java 架構或獨立 java 通用服務子產品的開發者,可以将 relproxy java 嵌入到你的架構中,這樣能透明地為架構的終端使用者提供代碼自動加載功能,隻需要進行一些必要的配置,而無需調用 relproxy api。

對使用 java 版的 relproxy,有兩種 api 可供調用:

jproxy 及其相關類:主要是靜态方法

java 腳本 api:基于接口

第二種方式更适合将 relproxy 嵌入到你的 java 架構中,這種方式是基于接口的,在你的 api 中無需暴露公共 relproxy

類,因為在架構中會執行啟動程式。我将使用比較簡單的 api:jproxyscriptenginefactory.create()。

jproxyscriptengine 的功能與 jproxy 相同,也就是說具有相同的方法。隻是這種情況下,隻需要使用接口。

一個簡單的例子是示範如何嵌入 relproxy 的最好方式。這個例子是 relproxy 的示例倉庫中包含的

relproxybuiltin(relproxy_builtin_ex

項目中)。它定義了兩個監聽器來實作注冊使用者端的代碼,一個監聽器顯示選項(option),另一個執行選擇的行為。

這個迷你架構和示例使用 netbeans 和 maven 開發完成。

有兩個包:

com.innowhere.relproxy_builtin_ex :迷你架構。子包 com.innowhere.relproxy_builtin_ex.impl 隻包含一個非公共的類。

com.innowhere.relproxy_builtin_ex_main :一個簡單的使用示例。

迷你架構(公共類和接口):

relproxybuiltinroot.java

1

2

3

4

5

6

7

8

9

10

<code>package</code> <code>com.innowhere.relproxy_builtin_ex;</code>

<code>import</code> <code>com.innowhere.relproxy_builtin_ex.impl.relproxybuiltinimpl;</code>

<code>public</code> <code>class</code> <code>relproxybuiltinroot</code>

<code>{</code>

<code>    </code><code>private</code> <code>final</code> <code>static</code> <code>relproxybuiltinimpl singleton =</code><code>new</code> <code>relproxybuiltinimpl();</code>

<code>    </code><code>public</code> <code>static</code> <code>relproxybuiltin get()</code>

<code>    </code><code>{</code>

<code>        </code><code>return</code> <code>singleton;</code>

<code>    </code><code>}</code>

<code>}</code>

relproxybuiltin.java

11

12

13

14

15

<code>import</code> <code>com.innowhere.relproxy.jproxy.jproxyscriptengine;</code>

<code>import</code> <code>java.io.inputstream;</code>

<code>import</code> <code>java.io.printstream;</code>

<code>public</code> <code>interface</code> <code>relproxybuiltin</code>

<code>    </code><code>public</code> <code>jproxyscriptengine getjproxyscriptengine();</code>

<code>    </code><code>public</code> <code>void</code> <code>addoutputlistener(outputlistener listener);</code>

<code>    </code><code>public</code> <code>void</code> <code>removeoutputlistener(outputlistener listener);</code>

<code>    </code><code>public</code> <code>int</code> <code>getoutputlistenercount();</code>

<code>    </code><code>public</code> <code>void</code> <code>addcommandlistener(commandlistener listener);</code>

<code>    </code><code>public</code> <code>void</code> <code>removecommandlistener(commandlistener listener);</code>

<code>    </code><code>public</code> <code>int</code> <code>getcommandlistenercount();</code>

<code>    </code><code>public</code> <code>void</code> <code>runloop(inputstream in,printstream out);</code>

outputlistener.java

<code>public</code> <code>interface</code> <code>outputlistener</code>

<code>    </code><code>public</code> <code>void</code> <code>write(printstream out);</code>

commandlistener.java

<code>public</code> <code>interface</code> <code>commandlistener</code>

<code>    </code><code>public</code> <code>void</code> <code>execute(string command,string input,printstream out);</code>

現在看一下實作細節,該類示範了怎樣簡單地内嵌 relproxy:

relproxybuiltinimpl.java

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

<code>package</code> <code>com.innowhere.relproxy_builtin_ex.impl;</code>

<code>import</code> <code>com.innowhere.relproxy.jproxy.jproxyscriptenginefactory;</code>

<code>import</code> <code>com.innowhere.relproxy_builtin_ex.commandlistener;</code>

<code>import</code> <code>com.innowhere.relproxy_builtin_ex.outputlistener;</code>

<code>import</code> <code>com.innowhere.relproxy_builtin_ex.relproxybuiltin;</code>

<code>import</code> <code>java.util.linkedhashset;</code>

<code>import</code> <code>java.util.scanner;</code>

<code>public</code> <code>class</code> <code>relproxybuiltinimpl</code><code>implements</code> <code>relproxybuiltin</code>

<code>    </code><code>protected</code> <code>jproxyscriptengine jproxyengine =</code><code>null</code><code>;</code>

<code>    </code><code>protected</code> <code>linkedhashset&lt;outputlistener&gt; outlisteners =</code><code>new</code> <code>linkedhashset&lt;outputlistener&gt;();</code>

<code>    </code><code>protected</code> <code>linkedhashset&lt;commandlistener&gt;  commandlisteners =</code><code>new</code> <code>linkedhashset&lt;commandlistener&gt;();</code>

<code>    </code><code>@override</code>

<code>    </code><code>public</code> <code>jproxyscriptengine getjproxyscriptengine()</code>

<code>        </code><code>if</code> <code>(jproxyengine ==</code><code>null</code><code>) jproxyengine = (jproxyscriptengine)jproxyscriptenginefactory.create().getscriptengine();</code>

<code>        </code><code>return</code> <code>jproxyengine;</code>

<code>    </code><code>public</code> <code>jproxyscriptengine getjproxyscriptengineifconfigured()</code>

<code>        </code><code>if</code> <code>(jproxyengine ==</code><code>null</code> <code>|| !jproxyengine.isenabled())</code>

<code>            </code><code>return</code> <code>null</code><code>;</code>

<code>    </code><code>public</code> <code>void</code> <code>addoutputlistener(outputlistener listener)</code>

<code>        </code><code>jproxyscriptengine jproxy = getjproxyscriptengineifconfigured();</code>

<code>        </code><code>if</code> <code>(jproxy !=</code><code>null</code><code>)</code>

<code>        </code><code>{</code>

<code>            </code><code>listener = jproxy.create(listener,outputlistener.</code><code>class</code><code>);</code>

<code>        </code><code>}</code>

<code>        </code><code>outlisteners.add(listener);</code>

<code>    </code><code>public</code> <code>void</code> <code>removeoutputlistener(outputlistener listener)</code>

<code>        </code><code>outlisteners.remove(listener);</code>

<code>    </code><code>public</code> <code>int</code> <code>getoutputlistenercount()</code>

<code>        </code><code>return</code> <code>outlisteners.size();</code>

<code>    </code><code>public</code> <code>void</code> <code>addcommandlistener(commandlistener listener)</code>

<code>            </code><code>listener = jproxy.create(listener,commandlistener.</code><code>class</code><code>);</code>

<code>        </code><code>commandlisteners.add(listener);</code>

<code>    </code><code>public</code> <code>void</code> <code>removecommandlistener(commandlistener listener)</code>

<code>        </code><code>commandlisteners.remove(listener);</code>

<code>    </code><code>public</code> <code>int</code> <code>getcommandlistenercount()</code>

<code>        </code><code>return</code> <code>commandlisteners.size();</code>

<code>    </code><code>public</code> <code>void</code> <code>runloop(inputstream in,printstream out)</code>

<code>        </code><code>scanner scanner =</code><code>new</code> <code>scanner(in);</code>

<code>        </code><code>while</code><code>(</code><code>true</code><code>)</code>

<code>            </code><code>out.print(</code><code>"enter phrase:"</code><code>);</code>

<code>            </code><code>string input = scanner.nextline();</code>

<code>            </code><code>out.println(</code><code>"command list:"</code><code>);</code>

<code>            </code><code>for</code><code>(outputlistener listener : outlisteners)</code>

<code>                </code><code>listener.write(out);</code>

<code>            </code><code>out.print(</code><code>"enter command (or quit):"</code><code>);</code>

<code>            </code><code>string command = scanner.nextline();</code>

<code>            </code><code>if</code> <code>(</code><code>"quit"</code><code>.equals(command))</code>

<code>                </code><code>break</code><code>;</code>

<code>            </code><code>for</code><code>(commandlistener listener : commandlisteners)</code>

<code>                </code><code>listener.execute(command,input,out);</code>

這三個方法足以解釋怎樣啟動 relproxy java 引擎,怎樣簡單地使用指令監聽器來注冊熱加載。

relproxybuiltinimpl.java (部分)

<code>@override</code>

<code>  </code><code>public</code> <code>jproxyscriptengine getjproxyscriptengine()</code>

<code>  </code><code>{</code>

<code>      </code><code>if</code> <code>(jproxyengine ==</code><code>null</code><code>) jproxyengine = (jproxyscriptengine)jproxyscriptenginefactory.create().getscriptengine();</code>

<code>      </code><code>return</code> <code>jproxyengine;</code>

<code>  </code><code>}</code>

<code>  </code><code>public</code> <code>jproxyscriptengine getjproxyscriptengineifconfigured()</code>

<code>      </code><code>if</code> <code>(jproxyengine ==</code><code>null</code> <code>|| !jproxyengine.isenabled())</code>

<code>          </code><code>return</code> <code>null</code><code>;</code>

<code>  </code><code>@override</code>

<code>  </code><code>public</code> <code>void</code> <code>addoutputlistener(outputlistener listener)</code>

<code>      </code><code>jproxyscriptengine jproxy = getjproxyscriptengineifconfigured();</code>

<code>      </code><code>if</code> <code>(jproxy !=</code><code>null</code><code>)</code>

<code>      </code><code>{</code>

<code>          </code><code>listener = jproxy.create(listener,outputlistener.</code><code>class</code><code>);</code>

<code>      </code><code>}</code>

<code>      </code><code>outlisteners.add(listener);</code>

公共方法 relproxybuiltin.getjproxyscriptengine() 必須在啟動時執行,用于配置 relproxy。如果沒有配置,relproxy 就不起作用。

請記住,通過 create(…) 建立的代理對象需要能正确的執行 hashcode() 方法和 equals(object) 方法,監聽器集合、監聽記錄依賴這兩個方法來差別監聽器對象。

這是基于控制台的示例代碼(名稱與 junit 類似,但确實不是 junit 的測試示例):

main.java

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

<code>package</code> <code>com.innowhere.relproxy_builtin_ex_main;</code>

<code>import</code> <code>com.innowhere.relproxy.relproxyonreloadlistener;</code>

<code>import</code> <code>com.innowhere.relproxy.jproxy.jproxy;</code>

<code>import</code> <code>com.innowhere.relproxy.jproxy.jproxycompilerlistener;</code>

<code>import</code> <code>com.innowhere.relproxy.jproxy.jproxyconfig;</code>

<code>import</code> <code>com.innowhere.relproxy.jproxy.jproxydiagnosticslistener;</code>

<code>import</code> <code>com.innowhere.relproxy.jproxy.jproxyinputsourcefileexcludedlistener;</code>

<code>import</code> <code>com.innowhere.relproxy_builtin_ex.relproxybuiltinroot;</code>

<code>import</code> <code>java.io.file;</code>

<code>import</code> <code>java.lang.reflect.method;</code>

<code>import</code> <code>java.net.url;</code>

<code>import</code> <code>java.util.arrays;</code>

<code>import</code> <code>java.util.list;</code>

<code>import</code> <code>javax.tools.diagnostic;</code>

<code>import</code> <code>javax.tools.diagnosticcollector;</code>

<code>import</code> <code>javax.tools.javafileobject;</code>

<code>public</code> <code>class</code> <code>main</code>

<code>    </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args)</code><code>throws</code> <code>exception</code>

<code>        </code><code>new</code> <code>main();</code>

<code>    </code><code>public</code> <code>main()</code>

<code>        </code><code>// note: netbeans console window works bad (no input) with maven test tasks http://stackoverflow.com/questions/3035351/broken-console-in-maven-project-using-netbeans</code>

<code>        </code><code>// this is why is not a really junit test.</code>

<code>        </code><code>setup();</code>

<code>        </code><code>try</code>

<code>            </code><code>maintest();</code>

<code>        </code><code>finally</code>

<code>            </code><code>teardown();</code>

<code>        </code><code>system.exit(</code><code>0</code><code>);</code>

<code>    </code><code>public</code> <code>void</code> <code>setup()</code>

<code>        </code><code>url res =</code><code>this</code><code>.getclass().getresource(</code><code>"/"</code><code>);</code><code>// .../target/classes/</code>

<code>        </code><code>// use example of relproxy in development time:</code>

<code>        </code><code>string inputpath = res.getfile() +</code><code>"/../../src/main/java/"</code><code>;</code>

<code>        </code><code>if</code> <code>(</code><code>new</code> <code>file(inputpath).exists())</code>

<code>            </code><code>system.out.println(</code><code>"relproxy to be enabled, development mode detected"</code><code>);</code>

<code>        </code><code>else</code>

<code>            </code><code>system.out.println(</code><code>"relproxy disabled, production mode detected"</code><code>);</code>

<code>            </code><code>return</code><code>;</code>

<code>        </code><code>jproxyinputsourcefileexcludedlistener excludedlistener =</code><code>new</code> <code>jproxyinputsourcefileexcludedlistener()</code>

<code>            </code><code>@override</code>

<code>            </code><code>public</code> <code>boolean</code> <code>isexcluded(file file, file rootfolderofsources)</code>

<code>            </code><code>{</code>

<code>                </code><code>string abspath = file.getabsolutepath();</code>

<code>                </code><code>if</code> <code>(file.isdirectory())</code>

<code>                </code><code>{</code>

<code>                    </code><code>return</code> <code>abspath.endswith(file.separatorchar +</code><code>"relproxy_builtin_ex"</code><code>);</code>

<code>                </code><code>}</code>

<code>                </code><code>else</code>

<code>                    </code><code>return</code> <code>abspath.endswith(file.separatorchar + main.</code><code>class</code><code>.getsimplename() +</code><code>".java"</code><code>);</code>

<code>            </code><code>}</code>

<code>        </code><code>};</code>

<code>        </code><code>string classfolder =</code><code>null</code><code>;</code><code>// optional</code>

<code>        </code><code>iterable&lt;string&gt; compilationoptions = arrays.aslist(</code><code>new</code> <code>string[]{</code><code>"-source"</code><code>,</code><code>"1.6"</code><code>,</code><code>"-target"</code><code>,</code><code>"1.6"</code><code>});</code>

<code>        </code><code>long</code> <code>scanperiod =</code><code>1000</code><code>;</code>

<code>        </code><code>relproxyonreloadlistener proxylistener =</code><code>new</code> <code>relproxyonreloadlistener() {</code>

<code>            </code><code>public</code> <code>void</code> <code>onreload(object objold, object objnew, object proxy, method method, object[] args) {</code>

<code>                </code><code>system.out.println(</code><code>"reloaded "</code> <code>+ objnew +</code><code>" calling method: "</code> <code>+ method);</code>

<code>        </code><code>jproxycompilerlistener compilerlistener =</code><code>new</code> <code>jproxycompilerlistener(){</code>

<code>            </code><code>public</code> <code>void</code> <code>beforecompile(file file)</code>

<code>                </code><code>system.out.println(</code><code>"before compile: "</code> <code>+ file);</code>

<code>            </code><code>public</code> <code>void</code> <code>aftercompile(file file)</code>

<code>                </code><code>system.out.println(</code><code>"after compile: "</code> <code>+ file);</code>

<code>        </code><code>jproxydiagnosticslistener diagnosticslistener =</code><code>new</code> <code>jproxydiagnosticslistener()</code>

<code>            </code><code>public</code> <code>void</code> <code>ondiagnostics(diagnosticcollector&lt;javafileobject&gt; diagnostics)</code>

<code>                </code><code>list&lt;diagnostic&lt;?</code><code>extends</code> <code>javafileobject&gt;&gt; diaglist = diagnostics.getdiagnostics();</code>

<code>                </code><code>int</code> <code>i =</code><code>1</code><code>;</code>

<code>                </code><code>for</code> <code>(diagnostic diagnostic : diaglist)</code>

<code>                   </code><code>system.err.println(</code><code>"diagnostic "</code> <code>+ i);</code>

<code>                   </code><code>system.err.println(</code><code>"  code: "</code> <code>+ diagnostic.getcode());</code>

<code>                   </code><code>system.err.println(</code><code>"  kind: "</code> <code>+ diagnostic.getkind());</code>

<code>                   </code><code>system.err.println(</code><code>"  line number: "</code> <code>+ diagnostic.getlinenumber());</code>

<code>                   </code><code>system.err.println(</code><code>"  column number: "</code> <code>+ diagnostic.getcolumnnumber());</code>

<code>                   </code><code>system.err.println(</code><code>"  start position: "</code> <code>+ diagnostic.getstartposition());</code>

<code>                   </code><code>system.err.println(</code><code>"  position: "</code> <code>+ diagnostic.getposition());</code>

<code>                   </code><code>system.err.println(</code><code>"  end position: "</code> <code>+ diagnostic.getendposition());</code>

<code>                   </code><code>system.err.println(</code><code>"  source: "</code> <code>+ diagnostic.getsource());</code>

<code>                   </code><code>system.err.println(</code><code>"  message: "</code> <code>+ diagnostic.getmessage(</code><code>null</code><code>));</code>

<code>                   </code><code>i++;</code>

<code>        </code><code>relproxybuiltin rpbroot = relproxybuiltinroot.get();</code>

<code>        </code><code>jproxyscriptengine engine = rpbroot.getjproxyscriptengine();</code>

<code>        </code><code>jproxyconfig jpconfig = jproxy.createjproxyconfig();</code>

<code>        </code><code>jpconfig.setenabled(</code><code>true</code><code>)</code>

<code>                </code><code>.setrelproxyonreloadlistener(proxylistener)</code>

<code>                </code><code>.setinputpath(inputpath)</code>

<code>                </code><code>.setjproxyinputsourcefileexcludedlistener(excludedlistener)</code>

<code>                </code><code>.setscanperiod(scanperiod)</code>

<code>                </code><code>.setclassfolder(classfolder)</code>

<code>                </code><code>.setcompilationoptions(compilationoptions)</code>

<code>                </code><code>.setjproxycompilerlistener(compilerlistener)</code>

<code>                </code><code>.setjproxydiagnosticslistener(diagnosticslistener);</code>

<code>        </code><code>engine.init(jpconfig);</code>

<code>        </code><code>system.out.println(</code><code>"relproxy running"</code><code>);</code>

<code>    </code><code>public</code> <code>void</code> <code>teardown()</code>

<code>        </code><code>engine.stop();</code>

<code>        </code><code>system.out.println(</code><code>"relproxy stopped"</code><code>);</code>

<code>    </code><code>public</code> <code>void</code> <code>maintest()</code>

<code>        </code><code>testlistener listener =</code><code>new</code> <code>testlistener();</code>

<code>        </code><code>rpbroot.addoutputlistener(listener);</code>

<code>        </code><code>asserttrue(rpbroot.getoutputlistenercount() ==</code><code>1</code><code>);</code>

<code>        </code><code>rpbroot.removeoutputlistener(listener);</code>

<code>        </code><code>asserttrue(rpbroot.getoutputlistenercount() ==</code><code>0</code><code>);</code>

<code>        </code><code>commandlistener commandlistener = listener.getcommandlistener();</code>

<code>        </code><code>rpbroot.addcommandlistener(commandlistener);</code>

<code>        </code><code>asserttrue(rpbroot.getcommandlistenercount() ==</code><code>1</code><code>);</code>

<code>        </code><code>rpbroot.removecommandlistener(commandlistener);</code>

<code>        </code><code>asserttrue(rpbroot.getcommandlistenercount() ==</code><code>0</code><code>);</code>

<code>        </code><code>rpbroot.runloop(system.in,system.out);</code>

<code>    </code><code>private</code> <code>static</code> <code>void</code> <code>asserttrue(</code><code>boolean</code> <code>res)</code>

<code>        </code><code>if</code> <code>(!res)</code><code>throw</code> <code>new</code> <code>runtimeexception(</code><code>"unexpected error"</code><code>);</code>

看一下這段代碼:

main.java (部分)

<code>url res =</code><code>this</code><code>.getclass().getresource(</code><code>"/"</code><code>);</code><code>// .../target/classes/</code>

<code>       </code><code>// use example of relproxy in development time:</code>

<code>       </code><code>string inputpath = res.getfile() +</code><code>"/../../src/main/java/"</code><code>;</code>

<code>       </code><code>if</code> <code>(</code><code>new</code> <code>file(inputpath).exists())</code>

<code>       </code><code>{</code>

<code>           </code><code>system.out.println(</code><code>"relproxy to be enabled, development mode detected"</code><code>);</code>

<code>       </code><code>}</code>

<code>       </code><code>else</code>

<code>           </code><code>system.out.println(</code><code>"relproxy disabled, production mode detected"</code><code>);</code>

<code>           </code><code>return</code><code>;</code>

<code>       </code><code>jproxyinputsourcefileexcludedlistener excludedlistener =</code><code>new</code> <code>jproxyinputsourcefileexcludedlistener()</code>

<code>           </code><code>@override</code>

<code>           </code><code>public</code> <code>boolean</code> <code>isexcluded(file file, file rootfolderofsources)</code>

<code>           </code><code>{</code>

<code>               </code><code>string abspath = file.getabsolutepath();</code>

<code>               </code><code>if</code> <code>(file.isdirectory())</code>

<code>               </code><code>{</code>

<code>                   </code><code>return</code> <code>abspath.endswith(file.separatorchar +</code><code>"relproxy_builtin_ex"</code><code>);</code>

<code>               </code><code>}</code>

<code>               </code><code>else</code>

<code>                   </code><code>return</code> <code>abspath.endswith(file.separatorchar + main.</code><code>class</code><code>.getsimplename() +</code><code>".java"</code><code>);</code>

<code>           </code><code>}</code>

<code>       </code><code>};</code>

我們擷取并注冊應用源代碼的根目錄,該代碼“可能”會被重新加載。

我們需要排除架構代碼,因為這顯然不是使用者的代碼(不需要重新加載)。此外,還需要排除 main.java

檔案,該檔案包含了測試代碼,也不需要重新加載,隻有 testlistener.java 類(與 main.java

在同一檔案夾下)需要(必需)重新加載。

最後 testlistener.java 類包含兩個監聽器,commandlistener 的實作采用匿名内部類的方式,主要目的是為了示範。

testlistener.java

<code>public</code> <code>class</code> <code>testlistener</code><code>implements</code> <code>outputlistener</code>

<code>    </code><code>public</code> <code>void</code> <code>write(printstream out)</code>

<code>        </code><code>out.println(</code><code>"uppercase"</code><code>);</code>

<code>        </code><code>out.println(</code><code>"lowercase"</code><code>);</code>

<code>    </code><code>public</code> <code>commandlistener getcommandlistener()</code>

<code>        </code><code>return</code> <code>new</code> <code>commandlistener()</code>

<code>            </code><code>public</code> <code>void</code> <code>execute(string command,string text,printstream out)</code>

<code>                </code><code>if</code> <code>(</code><code>"uppercase"</code><code>.equals(command))</code>

<code>                    </code><code>out.println(text.touppercase());</code>

<code>                </code><code>else</code> <code>if</code> <code>(</code><code>"lowercase"</code><code>.equals(command))</code>

<code>                    </code><code>out.println(text.tolowercase());</code>

<code>                    </code><code>out.println(</code><code>"unknown command:"</code> <code>+ command);</code>

先預定義可選項,然後執行 main 類。為了校驗 relproxy 是否起作用,可以在不停止程式的運作的基礎上增加一個新的可選項“same”。

<code>        </code><code>out.println(</code><code>"same"</code><code>); </code><code>// new</code>

<code>                </code><code>else</code> <code>if</code> <code>(</code><code>"same"</code><code>.equals(command))</code><code>// new</code>

<code>                    </code><code>out.println(text);</code><code>// new</code>

下一篇文章中将處理包含目前“same”的行為,不需要停止控制台應用。

注意:使用 relproxy 0.8.7 或更高的版本,這個版本在嵌入方式上做了改進。

來源:51cto