﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-爪哇岛-随笔分类-Java</title><link>http://www.blogjava.net/edsionsz/category/47921.html</link><description>关注java</description><language>zh-cn</language><lastBuildDate>Thu, 24 Feb 2011 12:23:37 GMT</lastBuildDate><pubDate>Thu, 24 Feb 2011 12:23:37 GMT</pubDate><ttl>60</ttl><item><title>java动态代理的实现</title><link>http://www.blogjava.net/edsionsz/archive/2011/02/24/345079.html</link><dc:creator>edsion</dc:creator><author>edsion</author><pubDate>Thu, 24 Feb 2011 08:18:00 GMT</pubDate><guid>http://www.blogjava.net/edsionsz/archive/2011/02/24/345079.html</guid><wfw:comment>http://www.blogjava.net/edsionsz/comments/345079.html</wfw:comment><comments>http://www.blogjava.net/edsionsz/archive/2011/02/24/345079.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/edsionsz/comments/commentRss/345079.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/edsionsz/services/trackbacks/345079.html</trackback:ping><description><![CDATA[<div id="cnblogs_post_body">
<p><span style="color: brown;">1.什么是动态代理? </span></p>
<p><span style="color: brown;">答：动态代理可以提供对另一个对象的访问，同时隐藏实际对象的具体事实。代理一般会实现
它所表示的实际对象的接口。代理可以访问实际对象，但是延迟实现实际对象的部分功能，实际对象实现系统的实际功能，代理对象对客户隐藏了实际对象。客户不
知道它是与代理打交道还是与实际对象打交道。<br />
2.为什么使用动态代理? </span></p>
<p><span style="color: brown;">答：因为动态代理可以对请求进行任何处理</span></p>
<p><span style="color: brown;">3.使用它有哪些好处? </span></p>
<p><span style="color: brown;">答：因为动态代理可以对请求进行任何处理</span><span style="color: brown;"><br />
4.哪些地方需要动态代理?</span></p>
<p><span style="color: brown;">答：不允许直接访问某些类；对访问要做特殊处理等</span></p>
<p><span style="color: brown;">&nbsp;</span></p>
<p>目前Java开发包中包含了对动态代理的支持，但是其实现只支持对<span style="color: #ff0000;"><strong>接口</strong></span>的的实现。 其实现主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。&nbsp;</p>
<p>Proxy类主要用来获取动态代理对象，InvocationHandler接口用来约束调用者实现</p>
<p>以下为模拟案例，通过动态代理实现在方法调用前后向控制台输出两句字符串</p>
<p>目录结构</p>
<p><img src="http://pic002.cnblogs.com/images/2011/270324/2011021810503038.png" alt="" /></p>
<p>&lt;br/&gt;</p>
<p>定义一个HelloWorld接口</p>
<div class="cnblogs_code">
<pre>
<div><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">package</span><span style="color: #000000;"> com.ljq.test;<br />
<br />
</span><span style="color: #008080;"> 2</span> <span style="color: #000000;"><br />
<br />
</span><span style="color: #008080;"> 3</span> <span style="color: #000000;">&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
<br />
</span><span style="color: #008080;"> 4</span> <span style="color: #008000;"> * 定义一个HelloWorld接口<br />
<br />
</span><span style="color: #008080;"> 5</span> <span style="color: #008000;"> * <br />
<br />
</span><span style="color: #008080;"> 6</span> <span style="color: #008000;"> * </span><span style="color: #808080;">@author</span><span style="color: #008000;"> jiqinlin<br />
<br />
</span><span style="color: #008080;"> 7</span> <span style="color: #008000;"> *<br />
<br />
</span><span style="color: #008080;"> 8</span> <span style="color: #008000;"> </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #008080;"> 9</span> <span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">interface</span><span style="color: #000000;"> HelloWorld {<br />
<br />
</span><span style="color: #008080;">10</span> <span style="color: #000000;">    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sayHelloWorld();<br />
<br />
</span><span style="color: #008080;">11</span> <span style="color: #000000;">}</span></div>
<br />
</pre>
</div>
<p>&lt;br/&gt;</p>
<p>类HelloWorldImpl是HelloWorld接口的实现</p>
<div class="cnblogs_code">
<pre>
<div><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">package</span><span style="color: #000000;"> com.ljq.test;<br />
<br />
</span><span style="color: #008080;"> 2</span> <span style="color: #000000;"><br />
</span><span style="color: #008080;"> 3</span> <span style="color: #000000;">&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
</span><span style="color: #008080;"> 4</span> <span style="color: #008000;"> * 类HelloWorldImpl是HelloWorld接口的实现<br />
</span><span style="color: #008080;"> 5</span> <span style="color: #008000;"> * <br />
</span><span style="color: #008080;"> 6</span> <span style="color: #008000;"> * </span><span style="color: #808080;">@author</span><span style="color: #008000;"> jiqinlin<br />
</span><span style="color: #008080;"> 7</span> <span style="color: #008000;"> *<br />
</span><span style="color: #008080;"> 8</span> <span style="color: #008000;"> </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #008080;"> 9</span> <span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> HelloWorldImpl </span><span style="color: #0000ff;">implements</span><span style="color: #000000;"> HelloWorld{<br />
</span><span style="color: #008080;">10</span> <span style="color: #000000;"><br />
</span><span style="color: #008080;">11</span> <span style="color: #000000;">    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sayHelloWorld() {<br />
<br />
</span><span style="color: #008080;">12</span> <span style="color: #000000;">        System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">HelloWorld!</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
<br />
</span><span style="color: #008080;">13</span> <span style="color: #000000;">    }<br />
<br />
</span><span style="color: #008080;">14</span> <span style="color: #000000;"><br />
<br />
</span><span style="color: #008080;">15</span> <span style="color: #000000;">}</span></div>
<br />
</pre>
</div>
<p>HelloWorldHandler是 InvocationHandler接口实现</p>
<div class="cnblogs_code">
<pre>
<div><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">package</span><span style="color: #000000;"> com.ljq.test;<br />
<br />
</span><span style="color: #008080;"> 2</span> <span style="color: #000000;"><br />
<br />
</span><span style="color: #008080;"> 3</span> <span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.lang.reflect.InvocationHandler;<br />
<br />
</span><span style="color: #008080;"> 4</span> <span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.lang.reflect.Method;<br />
<br />
</span><span style="color: #008080;"> 5</span> <span style="color: #000000;"><br />
<br />
</span><span style="color: #008080;"> 6</span> <span style="color: #000000;">&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
<br />
</span><span style="color: #008080;"> 7</span> <span style="color: #008000;"> * 实现在方法调用前后向控制台输出两句字符串<br />
<br />
</span><span style="color: #008080;"> 8</span> <span style="color: #008000;"> * <br />
<br />
</span><span style="color: #008080;"> 9</span> <span style="color: #008000;"> * </span><span style="color: #808080;">@author</span><span style="color: #008000;"> jiqinlin<br />
<br />
</span><span style="color: #008080;">10</span> <span style="color: #008000;"> *<br />
<br />
</span><span style="color: #008080;">11</span> <span style="color: #008000;"> </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #008080;">12</span> <span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> HelloWorldHandler </span><span style="color: #0000ff;">implements</span><span style="color: #000000;"> InvocationHandler{<br />
<br />
</span><span style="color: #008080;">13</span> <span style="color: #000000;">    </span><span style="color: #008000;">//</span><span style="color: #008000;">要代理的原始对象</span><span style="color: #008000;"><br />
<br />
</span><span style="color: #008080;">14</span> <span style="color: #008000;">&nbsp;</span><span style="color: #000000;">    </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Object obj;<br />
<br />
</span><span style="color: #008080;">15</span> <span style="color: #000000;">    <br />
<br />
</span><span style="color: #008080;">16</span> <span style="color: #000000;">    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> HelloWorldHandler(Object obj) {<br />
<br />
</span><span style="color: #008080;">17</span> <span style="color: #000000;">        </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();<br />
<br />
</span><span style="color: #008080;">18</span> <span style="color: #000000;">        </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.obj </span><span style="color: #000000;">=</span><span style="color: #000000;"> obj;<br />
<br />
</span><span style="color: #008080;">19</span> <span style="color: #000000;">    }<br />
<br />
</span><span style="color: #008080;">20</span> <span style="color: #000000;"><br />
<br />
</span><span style="color: #008080;">21</span> <span style="color: #000000;">    </span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
<br />
</span><span style="color: #008080;">22</span> <span style="color: #008000;">     * 在代理实例上处理方法调用并返回结果<br />
<br />
</span><span style="color: #008080;">23</span> <span style="color: #008000;">     * <br />
<br />
</span><span style="color: #008080;">24</span> <span style="color: #008000;">     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> proxy 代理类<br />
<br />
</span><span style="color: #008080;">25</span> <span style="color: #008000;">     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> method 被代理的方法<br />
<br />
</span><span style="color: #008080;">26</span> <span style="color: #008000;">     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> args 该方法的参数数组<br />
<br />
</span><span style="color: #008080;">27</span> <span style="color: #008000;">     </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #008080;">28</span> <span style="color: #000000;">    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Object invoke(Object proxy, Method method, Object[] args) </span><span style="color: #0000ff;">throws</span><span style="color: #000000;"> Throwable {<br />
<br />
</span><span style="color: #008080;">29</span> <span style="color: #000000;">        Object result </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
<br />
</span><span style="color: #008080;">30</span> <span style="color: #000000;">        </span><span style="color: #008000;">//</span><span style="color: #008000;">调用之前</span><span style="color: #008000;"><br />
<br />
</span><span style="color: #008080;">31</span> <span style="color: #008000;">&nbsp;</span><span style="color: #000000;">        doBefore();<br />
<br />
</span><span style="color: #008080;">32</span> <span style="color: #000000;">        </span><span style="color: #008000;">//</span><span style="color: #008000;">调用原始对象的方法</span><span style="color: #008000;"><br />
<br />
</span><span style="color: #008080;">33</span> <span style="color: #000000;">        result</span><span style="color: #000000;">=</span><span style="color: #000000;">method.invoke(obj, args);<br />
<br />
</span><span style="color: #008080;">34</span> <span style="color: #000000;">        </span><span style="color: #008000;">//</span><span style="color: #008000;">调用之后</span><span style="color: #008000;"><br />
<br />
</span><span style="color: #008080;">35</span> <span style="color: #000000;">        doAfter();<br />
<br />
</span><span style="color: #008080;">36</span> <span style="color: #000000;">        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> result;<br />
<br />
</span><span style="color: #008080;">37</span> <span style="color: #000000;">    }<br />
<br />
</span><span style="color: #008080;">38</span> <span style="color: #000000;">    <br />
<br />
</span><span style="color: #008080;">39</span> <span style="color: #000000;">    </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> doBefore(){<br />
<br />
</span><span style="color: #008080;">40</span> <span style="color: #000000;">        System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">before method invoke</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
<br />
</span><span style="color: #008080;">41</span> <span style="color: #000000;">    }<br />
<br />
</span><span style="color: #008080;">42</span> <span style="color: #000000;">    <br />
<br />
</span><span style="color: #008080;">43</span> <span style="color: #000000;">    </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> doAfter(){<br />
<br />
</span><span style="color: #008080;">44</span> <span style="color: #000000;">        System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">after method invoke</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
<br />
</span><span style="color: #008080;">45</span> <span style="color: #000000;">    }<br />
<br />
</span><span style="color: #008080;">46</span> <span style="color: #000000;">    <br />
<br />
</span><span style="color: #008080;">47</span> <span style="color: #000000;">}</span></div>
<br />
</pre>
</div>
<p>测试类</p>
<div class="cnblogs_code">
<pre>
<div><span style="color: #000000;">package com.ljq.test;<br />
<br />
<br />
<br />
import java.lang.reflect.InvocationHandler;<br />
<br />
import java.lang.reflect.Proxy;<br />
<br />
<br />
<br />
<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> HelloWorldTest {<br />
<br />
<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">static</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {<br />
<br />
HelloWorld helloWorld</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;"> HelloWorldImpl();<br />
<br />
InvocationHandler handler</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;"> HelloWorldHandler(helloWorld);<br />
<br />
<br />
<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">创建动态代理对象</span><span style="color: #008000;"><br />
<br />
</span><span style="color: #000000;">        HelloWorld proxy</span><span style="color: #000000;">=</span><span style="color: #000000;">(HelloWorld)Proxy.newProxyInstance(<br />
<br />
helloWorld.getClass().getClassLoader(), <br />
<br />
helloWorld.getClass().getInterfaces(), <br />
<br />
handler);<br />
<br />
proxy.sayHelloWorld();<br />
<br />
}<br />
<br />
}</span></div>
<br />
</pre>
</div>
<p>运行结果为：</p>
<p><img src="http://pic002.cnblogs.com/images/2011/270324/2011021810500381.png" alt="" /></p>
</div>
<img src ="http://www.blogjava.net/edsionsz/aggbug/345079.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/edsionsz/" target="_blank">edsion</a> 2011-02-24 16:18 <a href="http://www.blogjava.net/edsionsz/archive/2011/02/24/345079.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>