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();
}
 
}
  • 收藏
  • 评论
  • 举报