浏览 7267 次
锁定老帖子 主题:初探spring aop内部实现
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-12-21
SPRING是通过动态代理来实现AOP的,SPRING内部提供了2种实现机制 1.如果是有接口声明的类进行AOP,spring调用的是java.lang.reflection.Proxy类来做处理 org.springframework.aop.framework.JdkDynamicAopProxy public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { Class targetClass = this.advised.getTargetSource().getTargetClass(); logger.debug("Creating JDK dynamic proxy" + (targetClass != null ? " for [" + targetClass.getName() + "]" : "")); } Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); } org.springframework.aop.framework.ReflectiveMethodInvocation public Object proceed() throws Throwable { // We start with an index of -1 and increment early. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. return proceed(); } } else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } } 2.如果是没有接口声明的类呢?SPRING通过CGLIB包和内部类来实现 private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable { private final Object target; public StaticUnadvisedInterceptor(Object target) { this.target = target; } public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object retVal = methodProxy.invoke(target, args); return massageReturnTypeIfNecessary(proxy, target, retVal); } } /** * Method interceptor used for static targets with no advice chain, when the * proxy is to be exposed. */ private static class StaticUnadvisedExposedInterceptor implements MethodInterceptor, Serializable { private final Object target; public StaticUnadvisedExposedInterceptor(Object target) { this.target = target; } public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object oldProxy = null; try { oldProxy = AopContext.setCurrentProxy(proxy); Object retVal = methodProxy.invoke(target, args); return massageReturnTypeIfNecessary(proxy, target, retVal); } finally { AopContext.setCurrentProxy(oldProxy); } } } /** * Interceptor used to invoke a dynamic target without creating a method * invocation or evaluating an advice chain. (We know there was no advice * for this method.) */ private class DynamicUnadvisedInterceptor implements MethodInterceptor, Serializable { public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object target = advised.getTargetSource().getTarget(); try { Object retVal = methodProxy.invoke(target, args); return massageReturnTypeIfNecessary(proxy, target, retVal); } finally { advised.getTargetSource().releaseTarget(target); } } } /** * Interceptor for unadvised dynamic targets when the proxy needs exposing. */ private class DynamicUnadvisedExposedInterceptor implements MethodInterceptor, Serializable { public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object oldProxy = null; Object target = advised.getTargetSource().getTarget(); try { oldProxy = AopContext.setCurrentProxy(proxy); Object retVal = methodProxy.invoke(target, args); return massageReturnTypeIfNecessary(proxy, target, retVal); } finally { AopContext.setCurrentProxy(oldProxy); advised.getTargetSource().releaseTarget(target); } } } 我们自己也可以来试试 1.jdk proxy方式 先来一个接口 IHelloWorld.java package kris.aop.test; public interface IHelloWorld { public void print(String name); public void write(String sth); } 再来一个实现 HelloWorld.java package kris.aop.test; public class HelloWorld implements IHelloWorld { public void print(String name){ System.out.println("HelloWorld "+name); } public void write(String sth) { System.out.println("write "+sth); } } 代理类 DefaultInvocationHandler.java package kris.aop.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class DefaultInvocationHandler implements InvocationHandler { /** * 替换外部class调用的方法 * obj 外部已经已经包装好InvocationHandler的实例 * method 外部方法 * args 方法参数 */ public Object invoke(Object obj, Method method, Object[] args) throws Throwable { String s1 []={"kris"}; String s2 []={"anyone"}; IHelloWorld ihw=new HelloWorld(); System.out.println("start!"); method.invoke(ihw,args); method.invoke(ihw,s1); Object o=method.invoke(ihw,s2); System.out.println("stop!"); return o; } } 测试类 Test.java package kris.aop.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Test { public static void main(String args []){ Class clazz = new HelloWorld().getClass(); ClassLoader cl = clazz.getClassLoader(); Class classes [] = clazz.getInterfaces(); InvocationHandler ih=new DefaultInvocationHandler(); //用InvocationHandler给HelloWorld进行AOP包装 IHelloWorld ihw=(IHelloWorld) Proxy.newProxyInstance(cl,classes,ih); ihw.print("test"); ihw.write("test"); } } 2.用CGLIB包实现,首先不要忘了引入那个包 package kris.aop.cglib.test; public class HelloWorld { public void print(String name){ System.out.println("HelloWorld "+name); } public void write(String sth) { System.out.println("write "+sth); } public void print(){ System.out.println("HelloWorld"); } } 代理类(没用内部类,看起来清楚点) package kris.aop.cglib.test; import java.lang.reflect.Method; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class MethodInterceptorImpl implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println(method); proxy.invokeSuper(obj, args); return null; } } 测试类 package kris.aop.cglib.test; import net.sf.cglib.proxy.Enhancer; public class Test { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(HelloWorld.class); //设置回调方法实现类 enhancer.setCallback(new MethodInterceptorImpl()); //实例化已经添加回调实现的HELLOWORLD实例 HelloWorld my = (HelloWorld) enhancer.create(); my.print(); } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-02-01
清楚 谢谢
|
|
返回顶楼 | |
发表时间:2007-02-02
初级会员都这么高.....
|
|
返回顶楼 | |
发表时间:2007-04-14
引用 初级会员都这么高 初级才是高手,楼主,现在在研究Spring AOP的拦截具体的调用过程,能不能解释的稍微详细些,最上面的两段代码.
|
|
返回顶楼 | |
发表时间:2007-04-14
LargeBean 写道 初级会员都这么高.....
高不高,可不是拿论坛上面的等级来区分哦!!! |
|
返回顶楼 | |