首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

spring aop内部兑现

2012-09-15 
spring aop内部实现AOP功能强大,但是spring是如何来实现AOP技术的呢? SPRING是通过动态代理来实现AOP的,SP

spring aop内部实现

AOP功能强大,但是spring是如何来实现AOP技术的呢?
SPRING是通过动态代理来实现AOP的,SPRING内部提供了2种实现机制
1.如果是有接口声明的类进行AOP,spring调用的是java.lang.reflection.Proxy类来做处理

    org.springframework.aop.framework.JdkDynamicAopProxypublic 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.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(); ??????} ????}??

热点排行