﻿<?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-yuyee-随笔分类-aop</title><link>http://www.blogjava.net/yuyee/category/46754.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 03 Nov 2010 20:53:54 GMT</lastBuildDate><pubDate>Wed, 03 Nov 2010 20:53:54 GMT</pubDate><ttl>60</ttl><item><title>cglib入门</title><link>http://www.blogjava.net/yuyee/archive/2010/10/26/336181.html</link><dc:creator>羔羊</dc:creator><author>羔羊</author><pubDate>Tue, 26 Oct 2010 06:27:00 GMT</pubDate><guid>http://www.blogjava.net/yuyee/archive/2010/10/26/336181.html</guid><wfw:comment>http://www.blogjava.net/yuyee/comments/336181.html</wfw:comment><comments>http://www.blogjava.net/yuyee/archive/2010/10/26/336181.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyee/comments/commentRss/336181.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyee/services/trackbacks/336181.html</trackback:ping><description><![CDATA[代理为要控制访问的类提供了一种可行的途径，他为目标类引入一个中间层，JDK1.3后也有动态代理，不过性能不是很好，1.6有所加强。
<div>CGLIB是一个强大的代码生成包，在ASM上建立，在一些开源工具中经常可以看到他的身影，比如hibernate,spring。</div>
<div>CGLIB底层通过字节码处理框架ASM来将字节码生成新的类，在spring AOP中不强制使用CGLIB，默认是JDK动态代理。</div>
<div>CGLIB 包情况：</div>
<div>net.sf.cglib.core:底层字节码处理类，大部分与ASM有关。</div>
<div>net.sf.cglib.transform:编译期或运行期和类文件的转换</div>
<div>net.sf.cglib.proxy：实现创建代理和方法拦截器的类</div>
<div>net.sf.cglib.reflect:实现快速放射</div>
<div>net.sf.cglib.util:工具包</div>
<div>net.sf.cglib.beans:javabean相关工具类</div>
<div>通过CGLIB创建动态代理，本质上，他是动态的生成目标类的子类，覆盖目标类所有不是final的方法，并给他们设置好callback,因此，原有类的每个方法调用就会变成自定义的拦截方法。</div>
<div>创建动态代理时通常要用到如下api:net.sf.cglib.proxy.Callback这个接口，他是很关键的一个接口，所有被net.sf.cglib.proxy.Enhancer类调用的回调借口都要继承这个接口</div>
<div>如：public interface MethodInterceptor</div>
<div>extends Callback</div>
<div>{</div>
<div>&nbsp;&nbsp; &nbsp;/**</div>
<div>&nbsp;&nbsp; &nbsp; * All generated proxied methods call this method instead of the original method.</div>
<div>&nbsp;&nbsp; &nbsp; * The original method may either be invoked by normal reflection using the Method object,</div>
<div>&nbsp;&nbsp; &nbsp; * or by using the MethodProxy (faster).</div>
<div>&nbsp;&nbsp; &nbsp; * @param obj "this", the enhanced object</div>
<div>&nbsp;&nbsp; &nbsp; * @param method intercepted Method</div>
<div>&nbsp;&nbsp; &nbsp; * @param args argument array; primitive types are wrapped</div>
<div>&nbsp;&nbsp; &nbsp; * @param proxy used to invoke super (non-intercepted method); may be called</div>
<div>&nbsp;&nbsp; &nbsp; * as many times as needed</div>
<div>&nbsp;&nbsp; &nbsp; * @throws Throwable any exception may be thrown; if so, super method will not be invoked</div>
<div>&nbsp;&nbsp; &nbsp; * @return any value compatible with the signature of the proxied method. Method returning void will ignore this value.</div>
<div>&nbsp;&nbsp; &nbsp; * @see MethodProxy</div>
<div>&nbsp;&nbsp; &nbsp; */ &nbsp; &nbsp;</div>
<div>&nbsp;&nbsp; &nbsp;public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MethodProxy proxy) throws Throwable;</div>
<div><br />
</div>
<div>}</div>
<div>这个是基与方法的回调，第一个参数是代理对象，第二个是被拦截的方法对象，第三个是方法参数，第四个是方法的代理对象。</div>
<div>
<div>public class MyClass {</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public void method1() {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println("method1");</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public void method2() {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println("method2");</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
<div>}</div>
</div>
<div>拦截器：</div>
<div>
<div>public class MethodInterceptImpl implements MethodInterceptor {</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public Object intercept(Object arg0, Method arg1, Object[] arg2,</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>MethodProxy arg3) throws Throwable {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println(arg1.getName()+"--intercept");</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>arg3.invokeSuper(arg0, arg2);// 这里其实也可以用原来的方法对象来执行，但是性能上不如cglib的方法代理类</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>return null;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
<div>
<div>public class MainTest {</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public static void main(String[] args) {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>simpleTest();</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>private static void simpleTest() {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>Enhancer en = new Enhancer();</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>en.setCallback(new MethodInterceptImpl());</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>en.setSuperclass(MyClass.class);</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>MyClass m = (MyClass) en.create();</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>m.method1();</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>m.method2();</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
</div>
<div>结果：method1--intercept</div>
<div>method1</div>
<div>method2--intercept</div>
<div>method2</div>
<div>现实项目中可能存在某些需求，比如method1需要拦截，而method2不需要拦截。那我们可以对callback做下选择,使用net.sf.cglib.proxy.CallbackFilter做一些过滤。</div>
<div>
<div>public class MethodFilterImpl implements CallbackFilter {</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>private final static int execute = 0;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>private final static int unexecute = 1;</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public int accept(Method method) {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>String methodName = method.getName();</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>if("method1".equals(methodName)){</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>return execute;</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>}</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>return unexecute;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
<div><br />
</div>
<div>}</div>
</div>
<div><br />
</div>
<div>调用的时候需要给callback设置好索引位置，因为accept的返回值就是callbacks数组的索引位置。</div>
<div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>private static void filterTest() {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>Enhancer en = new Enhancer();</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>Callback[] callbacks = new Callback[] { new MethodInterceptImpl(),</div>
<div><span class="Apple-tab-span" style="white-space:pre">				</span>NoOp.INSTANCE };//这里拦截器的索引位置要与filter里的设置一致</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>en.setCallbacks(callbacks);</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>en.setSuperclass(MyClass.class);</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>en.setCallbackFilter(new MethodFilterImpl());</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>MyClass m = (MyClass) en.create();</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>m.method1();</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>m.method2();</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
</div>
<div>这里callbacks[1]这个位置使用了NoOp这个回调接口</div>
<div>
<div>public interface NoOp extends Callback</div>
<div>{</div>
<div>&nbsp;&nbsp; &nbsp;/**</div>
<div>&nbsp;&nbsp; &nbsp; * A thread-safe singleton instance of the &lt;code&gt;NoOp&lt;/code&gt; callback.</div>
<div>&nbsp;&nbsp; &nbsp; */</div>
<div>&nbsp;&nbsp; &nbsp;public static final NoOp INSTANCE = new NoOp() { };</div>
<div>}</div>
</div>
<div>这个callback其实就是直接把任务委派给这个方法在父类中的实现，其实也等同于没做什么额外的事情</div>
<div>执行结果：method1--intercept</div>
<div>method1</div>
<div>method2</div>
<div>method2 并未被MethodInterceptImpl拦截</div>
<div><br />
</div>
<div>}</div>
</div>
<img src ="http://www.blogjava.net/yuyee/aggbug/336181.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyee/" target="_blank">羔羊</a> 2010-10-26 14:27 <a href="http://www.blogjava.net/yuyee/archive/2010/10/26/336181.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Annotation来完成spring aop</title><link>http://www.blogjava.net/yuyee/archive/2010/10/25/336106.html</link><dc:creator>羔羊</dc:creator><author>羔羊</author><pubDate>Mon, 25 Oct 2010 08:52:00 GMT</pubDate><guid>http://www.blogjava.net/yuyee/archive/2010/10/25/336106.html</guid><description><![CDATA[spring AOP中，可以通过annotation来简化XML上的配置，可以很灵活的使切面切入到自己想要的方法上，而不需要象aop:config里一定要切入到特定命名方法上
<div>使用annotation来表示pointcut，需要在xml里配置org.springframework.aop.support.annotation.AnnotationMatchingPointcut，</div>
<div>如：&lt;bean name="timeoutPointcut"</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>class="org.springframework.aop.support.annotation.AnnotationMatchingPointcut"&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>&lt;constructor-arg index="0"</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>value="com.hengtian.fxfundsystem.aop.annotation.UseAOPAnnotation"&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>&lt;/constructor-arg&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>&lt;constructor-arg index="1"</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>value="com.hengtian.fxfundsystem.aop.annotation.TimeoutAnnotation" /&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>&lt;/bean&gt;</div>
<div>第一个参数是标在目标类上的annotation,第二天参数是标注在方法上的Annotation</div>
<div>因此，首先要在自己的工程里定义2个annotation，一个为TimeoutAnnotation，一个为UseAOPAnnotation</div>
<div>
<div>@Target({ElementType.TYPE })//表示类标注</div>
<div>@Retention(RetentionPolicy.RUNTIME)</div>
<div>@Inherited</div>
<div>public @interface UseAOPAnnotation {</div>
<div><br />
</div>
<div>}</div>
</div>
<div>
<div>@Target({ElementType.METHOD})//表示方法标注</div>
<div>@Retention(RetentionPolicy.RUNTIME)</div>
<div>public @interface TimeoutAnnotation {</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>/**</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> * 默认值(-1)：表示不启用超时</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> */</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public static final long DefaultValue = -1;</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>/**</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> * 超时时间，单位是ms</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> *&nbsp;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> * @return</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> */</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>long value() default DefaultValue;</div>
<div><br />
</div>
<div>}</div>
</div>
<div>在需要AOP的类上使用</div>
<div>
<div>@UseAOPAnnotation</div>
<div>@Component("StrongDuck") &nbsp;</div>
<div>public class StrongDuck {</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>@TimeoutAnnotation(70000)</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public void say(){</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println("I am a strong duck");</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
<div>}</div>
<div>timeout通知：</div>
<div>
<div>public class TimeoutAdvice implements MethodInterceptor {</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>/*</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> * (non-Javadoc)</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> *&nbsp;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> * @see</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> * org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> * .MethodInvocation)</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span> */</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public Object invoke(final MethodInvocation methodInvocation)</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>throws Throwable {</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>Method targetMethod = methodInvocation.getMethod();</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>TimeoutAnnotation timeoutAnnotation = targetMethod</div>
<div><span class="Apple-tab-span" style="white-space:pre">				</span>.getAnnotation(TimeoutAnnotation.class);</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>if (timeoutAnnotation != null) {</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>long waitTime = timeoutAnnotation.value();</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>if (waitTime != TimeoutAnnotation.DefaultValue) {</div>
<div><span class="Apple-tab-span" style="white-space:pre">				</span>Future&lt;?&gt; task = ThreadManager.ExecutorService</div>
<div><span class="Apple-tab-span" style="white-space:pre">						</span>.submit(encapsulateSyncToAsync(methodInvocation));</div>
<div><span class="Apple-tab-span" style="white-space:pre">				</span>return getAsyncResult(waitTime, task);</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>}</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>}</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>return methodInvocation.proceed();</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
</div>
</div>
<div>XML中配置拦截器：</div>
<div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>&lt;bean id="timeoutInterceptor" class="org.springframework.aop.support.DefaultPointcutAdvisor"&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>&lt;property name="advice" ref="timeoutAdvice" /&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>&lt;property name="pointcut" ref="timeoutPointcut" /&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>&lt;/bean&gt;</div>
<div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>&lt;bean</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>&lt;property name="proxyTargetClass"&gt;&lt;!-- 基于类的代理 --&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>&lt;value&gt;true&lt;/value&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>&lt;/property&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>&lt;/bean&gt;</div>
</div>
</div>
<div>这样，spring就会为你生成aop代理类实现AOP</div>
<div><br />
</div>
<div><br />
</div>
<img src ="http://www.blogjava.net/yuyee/aggbug/336106.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyee/" target="_blank">羔羊</a> 2010-10-25 16:52 <a href="http://www.blogjava.net/yuyee/archive/2010/10/25/336106.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDK代理</title><link>http://www.blogjava.net/yuyee/archive/2010/10/25/336046.html</link><dc:creator>羔羊</dc:creator><author>羔羊</author><pubDate>Sun, 24 Oct 2010 16:20:00 GMT</pubDate><guid>http://www.blogjava.net/yuyee/archive/2010/10/25/336046.html</guid><description><![CDATA[JDK代理以前性能不怎么样，但1.6版本却有很大提升
<div>
<div>
<div>/**</div>
<div>&nbsp;* 行为接口</div>
<div>&nbsp;*&nbsp;</div>
<div>&nbsp;* @author Administrator</div>
<div>&nbsp;*&nbsp;</div>
<div>&nbsp;*/</div>
<div>public interface Study {</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public void doStudy();</div>
<div>}</div>
</div>
</div>
<div>
<div>/**</div>
<div>&nbsp;* 目标对象</div>
<div>&nbsp;*&nbsp;</div>
<div>&nbsp;* @author Administrator</div>
<div>&nbsp;*&nbsp;</div>
<div>&nbsp;*/</div>
<div>public class StudyImpl implements Study {</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>@Override</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public void doStudy() {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println("study jdk proxy");</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
<div><br />
</div>
<div>}</div>
</div>
<div><br />
</div>
<div>
<div><br />
</div>
<div>/**</div>
<div>&nbsp;* 代理类</div>
<div>&nbsp;* @author Administrator</div>
<div>&nbsp;*</div>
<div>&nbsp;*/</div>
<div>public class JDKProxy implements InvocationHandler {</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>private Study s;</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public JDKProxy(Study s) {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>this.s = s;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>@Override</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public Object invoke(Object proxy, Method method, Object[] args)</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>throws Throwable {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println("before jdkproxy");</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>method.invoke(s, args);</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>System.out.println("after jdkproxy");</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>return null;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
<div>}</div>
<div><br />
</div>
</div>
<div>应用中进行调用：</div>
<div>
<div>
<div>public class Test {</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public static void main(String[] args) throws SecurityException,</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>NoSuchMethodException, IllegalArgumentException,</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>InstantiationException, IllegalAccessException,</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>InvocationTargetException {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>Class clazz = StudyImpl.class;//获取目标类的Class对象</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>Study st = new StudyImpl();//实例化一个目标类</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>Class proxClass = Proxy.getProxyClass(clazz.getClassLoader(), clazz</div>
<div><span class="Apple-tab-span" style="white-space:pre">				</span>.getInterfaces());//通过Proxy静态方法，获取一个于目标类实现同样接口的Class对象，也可以说是兄弟类</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>Constructor c = proxClass</div>
<div><span class="Apple-tab-span" style="white-space:pre">				</span>.getConstructor(new Class[] { InvocationHandler.class });//给这个类一个指定的公开的构造方法</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>Study ds = (Study) c.newInstance(new Object[] { new JDKProxy(st) });//实例化一个代理类</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
<div>}</div>
</div>
</div>
<img src ="http://www.blogjava.net/yuyee/aggbug/336046.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyee/" target="_blank">羔羊</a> 2010-10-25 00:20 <a href="http://www.blogjava.net/yuyee/archive/2010/10/25/336046.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AOP日记</title><link>http://www.blogjava.net/yuyee/archive/2010/10/24/336045.html</link><dc:creator>羔羊</dc:creator><author>羔羊</author><pubDate>Sun, 24 Oct 2010 15:48:00 GMT</pubDate><guid>http://www.blogjava.net/yuyee/archive/2010/10/24/336045.html</guid><description><![CDATA[<div><br />
</div>
<div>&nbsp;&nbsp;最近在学着总结，因为常感觉做完东西，长久不用，过段时间就忘，下次想复习下都不行。</div>
<div>&nbsp;AOP，面向方面编程，我们系统中有很多组件组成，每一个组件负责一部分业务功能,</div>
<div>&nbsp;但是这些组件往往又带有一部分核心功能外的附加功能，而且是重复代码，如：日志，安全，事务！ 通过AOP，实现这些附加功能的可重复利用。</div>
<div>&nbsp;</div>
<div>&nbsp;AOP其实可以看作是代理模式的扩展,写一个简单的代理</div>
<div>&nbsp;</div>
<div>public class ProxySubject implements ProxyInterface {</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>private Subject innerObj;// 真正的对象</div>
<div><br />
</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>@Override</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>public void handle() {</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>innerObj = new Subject();</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>// 做额外的事情</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>innerObj.handle();// 真正的处理业务</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>// 做额外的事情</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>}</div>
<div>}</div>
<p>
</p>
<p>&nbsp;Aop中叫代理类为advice,可以有多个连接起来，一个事件链</p>
<p>&nbsp;&nbsp;实现AOP，还需要涉及到JAVA的反射，通过反射，获取method对象，并执行方法，AOP规范包里有个接口</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>public interface MethodInterceptor extends Interceptor {</p>
<p><span class="Apple-tab-span" style="white-space:pre">	</span></p>
<p>&nbsp;&nbsp; &nbsp;</p>
<p>&nbsp;&nbsp; &nbsp; *Implement this method to perform extra treatments before and</p>
<p>&nbsp;&nbsp; &nbsp; * after the invocation. Polite implementations would certainly</p>
<p>&nbsp;&nbsp; &nbsp; * like to invoke {@link Joinpoint#proceed()}.</p>
<p>&nbsp;&nbsp; &nbsp; *</p>
<p>&nbsp;&nbsp; &nbsp; * @param invocation the method invocation joinpoint</p>
<p>&nbsp;&nbsp; &nbsp; * @return the result of the call to {@link</p>
<p>&nbsp;&nbsp; &nbsp; * Joinpoint#proceed()}, might be intercepted by the</p>
<p>&nbsp;&nbsp; &nbsp; * interceptor.</p>
<p>&nbsp;&nbsp; &nbsp; *</p>
<p>&nbsp;&nbsp; &nbsp; * @throws Throwable if the interceptors or the</p>
<p>&nbsp;&nbsp; &nbsp; * target-object throws an exception. &nbsp;</p>
<p>&nbsp;&nbsp; &nbsp; Object invoke(MethodInvocation invocation) throws Throwable;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;｝</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;通过 MethodInvocation的 getMethod()获得方法对象，并执行</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;这样，如果你一个类中有很多方法，就可以通过这么一个</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;AOP中生成代理类有3种方式，</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;1.静态编译时期，源代码生成，为每个符合条件的类生成一个代理类</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;2.静态字节码增强通过ASM/CGLIB分析字节码，生成代理类</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;3.动态字节码增强，spring aop就是这样,ASM/CGLIB或者JDK的动态代理</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;AOP的原理可以理解为代理模式+放射+自动字节码生成</p>
<p>Spring中动态代理有2种方式，一种是通过CGLIB，一种是JDK。</p>
<p>什么时候采用JDK什么时候采用CGLIB动态生成，主要取决于你又没实现接口，JDK动态代理需要目标类实现某接口，而CGLIB则是生成目标类的子类</p>
<p>
</p>
<p>public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {</p>
<p><span class="Apple-tab-span" style="white-space:pre">		</span>if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {</p>
<p><span class="Apple-tab-span" style="white-space:pre">			</span>Class targetClass = config.getTargetClass();</p>
<p><span class="Apple-tab-span" style="white-space:pre">			</span>if (targetClass == null) {</p>
<p><span class="Apple-tab-span" style="white-space:pre">				</span>throw new AopConfigException("TargetSource cannot determine target class: " +</p>
<p><span class="Apple-tab-span" style="white-space:pre">						</span>"Either an interface or a target is required for proxy creation.");</p>
<p><span class="Apple-tab-span" style="white-space:pre">			</span>}</p>
<p><span class="Apple-tab-span" style="white-space:pre">			</span>if (targetClass.isInterface()) {</p>
<p><span class="Apple-tab-span" style="white-space:pre">				</span>return new JdkDynamicAopProxy(config);</p>
<p><span class="Apple-tab-span" style="white-space:pre">			</span>}</p>
<p><span class="Apple-tab-span" style="white-space:pre">			</span>if (!cglibAvailable) {</p>
<p><span class="Apple-tab-span" style="white-space:pre">				</span>throw new AopConfigException(</p>
<p><span class="Apple-tab-span" style="white-space:pre">						</span>"Cannot proxy target class because CGLIB2 is not available. " +</p>
<p><span class="Apple-tab-span" style="white-space:pre">						</span>"Add CGLIB to the class path or specify proxy interfaces.");</p>
<p><span class="Apple-tab-span" style="white-space:pre">			</span>}</p>
<p><span class="Apple-tab-span" style="white-space:pre">			</span>return CglibProxyFactory.createCglibProxy(config);</p>
<p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p>
<p><span class="Apple-tab-span" style="white-space:pre">		</span>else {</p>
<p><span class="Apple-tab-span" style="white-space:pre">			</span>return new JdkDynamicAopProxy(config);</p>
<p><span class="Apple-tab-span" style="white-space:pre">		</span>}</p>
<p><span class="Apple-tab-span" style="white-space:pre">	</span>}</p>
<p>这个是DefaultAopProxyFactory里创建代理类的方法</p>
<p><br />
</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/yuyee/aggbug/336045.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyee/" target="_blank">羔羊</a> 2010-10-24 23:48 <a href="http://www.blogjava.net/yuyee/archive/2010/10/24/336045.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>