设为首页 加入收藏

TOP

Spring AOP两种实现机制是什么?
2014-09-29 03:00:05 来源: 作者: 【 】 浏览:45
Tags:Spring AOP 实现 机制 什么

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) {


// eva luate dynamic method matcher here: static part will already have


// been eva luated 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 eva luated 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 eva luating 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();


}



}


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇2014年最新Java笔试题及答案 下一篇AOP有三种植入切面的方法,分别是..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: