发布网友 发布时间:2022-04-22 14:08
共1个回答
热心网友 时间:2022-04-14 08:15
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.ReflectiveMethodInvocationpublic 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.javapackage kris.aop.test; public interface IHelloWorld { public void print(String name);public void write(String sth);} 再来一个实现HelloWorld.javapackage 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.javapackage 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.javapackage 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();} }来自:求助得到的回答