<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[Heck's  Blog]]></title> 
<link>https://www.heckjj.com/index.php</link> 
<description><![CDATA[一瞬间的决定，往往可以改变很多，事实上，让自己成功的往往不是知识，是精神！ 如果你总是为自己找借口，那只好让成功推迟。执行力，今天！]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[Heck's  Blog]]></copyright>
<item>
<link>https://www.heckjj.com/post//</link>
<title><![CDATA[JAVA的动态代理机制和Spring的实现方式]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[编程杂谈]]></category>
<pubDate>Sun, 30 Mar 2014 06:40:35 +0000</pubDate> 
<guid>https://www.heckjj.com/post//</guid> 
<description>
<![CDATA[ 
	JAVA 代理实现<br/>代理的实现分动态代理和静态代理，静态代理的实现是对已经生成了的JAVA类进行封装。<br/>动态代理则是在运行时生成了相关代理类，在JAVA中生成动态代理一般有两种方式。<br/><br/><span style="font-size: 18px;"><strong>JDK自带实现方法</strong></span><br/>JDK实现代理生成，是用类 java.lang.reflect.Proxy, 实现方式如下<br/><br/>Eg:<br/><textarea name="code" class="java" rows="15" cols="100">
public class JDKProxy &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static Object getPoxyObject(final Object c) &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Proxy.newProxyInstance(c.getClass().getClassLoader(), c.getClass().getInterfaces(),// JDK实现动态代理，但JDK实现必须需要接口

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new InvocationHandler() &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Object invoke(Object proxy, Method method, Object[] args) throws Throwable &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object reObj = null;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.print(&quot;you say: &quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reObj = method.invoke(c, args);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot; [&quot; + Calendar.getInstance().get(Calendar.HOUR) + &quot;:&quot;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ Calendar.getInstance().get(Calendar.MINUTE) + &quot; &quot;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ Calendar.getInstance().get(Calendar.SECOND) + &quot;]&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return reObj;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&#125;
</textarea><br/><br/><br/>测试代理类方法<br/><textarea name="code" class="java" rows="15" cols="100">
public class TestForPoxy &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void main(String[] args) &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServiceTest service = new ServiceTestImpl();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(service.getClass().getSimpleName());

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServiceTest poxyService = (ServiceTest) JDKProxy.getPoxyObject(service);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(poxyService.getClass().getSuperclass());

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;poxyService.saySomething(&quot;hello,My QQ code is 332003231.&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;poxyService.saySomething(&quot;what &#039;s your name?&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;poxyService.saySomething(&quot;only for test,hehe.&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&#125;
</textarea><br/><br/>1、Proxy实现代理的目标类必须有实现接口<br/><br/>2、 生成出来的代理类为接口实现类，和目标类不能进行转换，只能转为接口实现类进行调用<br/><br/>明显特点：通过此方法生成出来的类名叫做 $Proxy0<br/><br/><span style="font-size: 18px;"><strong>用CGLIB包实现</strong></span><br/>CGLIB是一个开源项目，官方网址是：<a href="http://cglib.sourceforge.net/" target="_blank">http://cglib.sourceforge.net/</a>，可以去上面下载最新JAR包，<br/><br/>本项目用的是cglib-3.0.jar<br/><br/>本项目还加入了依赖JAR包asm-4.0.jar，asm-util-4.0.jar<br/><br/>实现方式如下<br/><br/>Eg：<br/><textarea name="code" class="java" rows="15" cols="100">
public class CGLIBProxy &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static Object getPoxyObject(Object c) &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Enhancer enhancer = new Enhancer();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enhancer.setSuperclass(c.getClass());

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enhancer.setCallback(new MethodInterceptor() &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy proxy) throws Throwable &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.print(&quot;you say: &quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy.invokeSuper(arg0, arg2);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot; [&quot; + Calendar.getInstance().get(Calendar.HOUR) + &quot;:&quot;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ Calendar.getInstance().get(Calendar.MINUTE) + &quot; &quot; + Calendar.getInstance().get(Calendar.SECOND)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ &quot;]&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return enhancer.create();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&#125;
</textarea><br/>测试代理类方法<br/><textarea name="code" class="java" rows="15" cols="100">
public class TestForPoxy &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void main(String[] args) &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServiceTest service = new ServiceTestImpl();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(service.getClass().getSimpleName());

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ServiceTest poxyService = (ServiceTest) JDKProxy.getPoxyObject(service);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServiceTest poxyService = (ServiceTest) CGLIBProxy.getPoxyObject(service);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(poxyService.getClass().getSuperclass());

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;poxyService.saySomething(&quot;hello,My QQ code is 332003231.&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;poxyService.saySomething(&quot;what &#039;s your name?&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;poxyService.saySomething(&quot;only for test,hehe.&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&#125;
</textarea><br/> <br/><br/>1， CGLIB实现方式是对代理的目标类进行继承<br/><br/>2， 生成出了的代理类可以没方法，生成出来的类可以直接转换成目标类或目标类实现接口的实现类，因JAVA向上转换<br/><br/>明显特点：通过输出看出，看出生成出的代理类的parent类为代理的目标类<br/><br/> <br/><br/>Spring&nbsp;&nbsp;AOP的代理类机制分析<br/> <br/><br/>在spring中，bean都是由动态代理生成出来的，那么到底是用JDK的Proxy类实现呢，还是用CGLIB方式实现呢。<br/><br/>AOP&nbsp;&nbsp;Spring需要的依赖JAR包有:<br/><br/>spring-asm-3.2.0.M1.jar<br/><br/>spring-beans-3.2.0.M1.jar<br/><br/>spring-context-3.2.0.M1.jar<br/><br/>spring-core-3.2.0.M1.jar<br/><br/>spring-expression-3.2.0.M1.jar<br/><br/>spring-aop-3.2.0.M1.jar<br/><br/>spring-aspects-3.2.0.M1.jar<br/><br/>commons&#92;commons-logging-1.1.1&#92;commons-logging-1.1.1.jar<br/><br/>aopalliance&#92;aopalliance.jar<br/><br/>lib&#92;aspectjweaver.jar<br/><br/> <br/><br/><span style="font-size: 18px;"><strong>实现AOP</strong></span><br/><br/>先简单的实现AOP<br/>配置如下<br/><textarea name="code" class="xml" rows="15" cols="100">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;

&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation=&quot;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/beans

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/aop 

&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/aop/spring-aop-3.2.xsd&quot;&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean id=&quot;test&quot; class=&quot;org.ben.spring.service.Test&quot; /&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean id=&quot;aspectBean&quot; class=&quot;org.ben.spring.TestAspect&quot; /&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- 对Test类进行AOP拦截 --&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;aop:config&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;aop:aspect id=&quot;TestAspect&quot; ref=&quot;aspectBean&quot;&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--配置切面--&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;aop:pointcut id=&quot;businessService&quot;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expression=&quot;execution(* org.ben.spring.service.Test.say(..))&quot; /&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;aop:before pointcut-ref=&quot;businessService&quot; method=&quot;doBefore&quot; /&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;aop:after pointcut-ref=&quot;businessService&quot; method=&quot;doAfter&quot; /&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/aop:aspect&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/aop:config&gt;

&lt;/beans&gt;
</textarea><br/>然后进行运行结果如下，表示AOP拦截成功<br/><br/>TestAspect.java<br/><textarea name="code" class="java" rows="15" cols="100">
package org.ben.spring;

public class TestAspect &#123;
&nbsp;&nbsp;public void doBefore() &#123;
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;do something in befor&quot;);
&nbsp;&nbsp;&#125;

&nbsp;&nbsp;public void doAfter() &#123;
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;do something in after&quot;);
&nbsp;&nbsp;&#125;
&#125;

</textarea><br/><br/>AOP测试类<br/><textarea name="code" class="java" rows="15" cols="100">
public class TestBeans &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void main(String[] args) &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext ctx = new ClassPathXmlApplicationContext(&quot;test.xml&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Test test=(Test) ctx.getBean(&quot;test&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(test.getClass().getSimpleName());

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;test.say();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&#125;
</textarea><br/>输出：<br/><br/>do something in befor<br/><br/>welcome for test,My QQ is 332003231<br/><br/>do something in after<br/><br/><span style="font-size: 18px;"><strong>打印代理类的生成方式</strong></span><br/> <br/><br/>第一种情况, Test不实现任何接口，代码如下<br/><textarea name="code" class="java" rows="15" cols="100">
public class Test &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void say() &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;welcome for test，My QQ is 332003231&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&#125;
</textarea><br/><br/>在TestBeans中加入打印当前对象的名称<br/><br/>如下：<br/><textarea name="code" class="java" rows="15" cols="100">
ApplicationContext ctx = new ClassPathXmlApplicationContext(&quot;test.xml&quot;);

Test test=(Test) ctx.getBean(&quot;test&quot;);

System.out.println(test.getClass().getSimpleName());

System.out.println(&quot;super class is &quot;+test.getClass().getSuperclass());

test.say();
</textarea><br/>输出：<br/><br/>Test$$EnhancerByCGLIB$$4791b36c<br/><br/>super class is class org.ben.spring.service.Test<br/><br/>do something in befor<br/><br/>welcome for test,My QQ is 332003231<br/><br/>do something in after<br/><br/> <br/><br/>明显看到用了AOP之后，输出的是代理类对象Test$$EnhancerByCGLIB$$bb9b6a7c.而且它的父类是我们的代理目标类。说明是有CGLIB生成的<br/> <br/><br/>第二种情况<br/><br/>XML的配置不变，改变代理目标类Test的实现方法，如下<br/><textarea name="code" class="java" rows="15" cols="100">
public class Test implements TestInter&#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void say() &#123;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;welcome for test，My QQ is 332003231&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&#125;
</textarea><br/>和原来不同的是多继承了一个接口，接口中定义了say()方法<br/><br/>在TestBeans中加入打印当前对象的名称<br/><br/>如下：<br/><textarea name="code" class="java" rows="15" cols="100">
ApplicationContext ctx = new ClassPathXmlApplicationContext(&quot;test.xml&quot;);

TestInter test=(TestInter) ctx.getBean(&quot;test&quot;);

System.out.println(test.getClass().getSimpleName());

System.out.println(&quot;super class is &quot;+test.getClass().getSuperclass());

test.say();
</textarea><br/> <br/><br/>输出：<br/><br/>$Proxy0<br/><br/>super class is class java.lang.reflect.Proxy<br/><br/>do something in befor<br/><br/>welcome for test,My QQ is 332003231<br/><br/>do something in after<br/><br/><span style="font-size: 18px;"><strong>结论</strong></span><br/>Spring AOP中，当拦截对象实现了接口时，生成方式是用JDK的Proxy类。当没有实现任何接口时用的是GCLIB开源项目生成的拦截类的子类.<br/><br/> 附上本文测试的源码内容 <a href="attachment.php?fid=129">点击这里下载文件</a><br/>Tags - <a href="https://www.heckjj.com/tags/%25E5%258A%25A8%25E6%2580%2581%25E4%25BB%25A3%25E7%2590%2586/" rel="tag">动态代理</a> , <a href="https://www.heckjj.com/tags/spring/" rel="tag">spring</a> , <a href="https://www.heckjj.com/tags/aop/" rel="tag">aop</a> , <a href="https://www.heckjj.com/tags/%25E4%25BB%25A3%25E7%2590%2586%25E6%259C%25BA%25E5%2588%25B6/" rel="tag">代理机制</a> , <a href="https://www.heckjj.com/tags/gclib/" rel="tag">gclib</a>
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post//#blogcomment</link>
<title><![CDATA[[评论] JAVA的动态代理机制和Spring的实现方式]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>https://www.heckjj.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>