springAOP代理机制.ppt
,CONFIDENTIAL,Spring AOP入门-代理机制,中国北京:电话:(010)82780848/62969799地址:北京市海淀区创业中路36号 留学人员创业园306室,目标,什么是AOP代理机制静态代理动态代理AOP的几个基本概念,AOP,AOP Aspect Oriented Programming的缩写,意思是面向方面编程。AOP实际是GoF设计模式的延续,设计模式孜孜不倦所追求的就是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。Aspect是程序设计一个新的中心,AOP並不取代OOP,两者各有各的角色,将职责各自分配给Object与Aspect,会使得程序中各个组件的角色更为清楚。,代理机制,静态代理代理对象HelloProxy将代理真正的HelloSpeaker实现类来执行hello()等方法,並在其前后加上日志记录的动作,这使得我们的HelloSpeaker在执行业务方法时不必介入日志记录动作,可以专心于自己的职责。注意:代理对象的一个接口只服务于一种类的对象,而且如果要代理的方法很多,我们势必要为每个方法进行代理,静态代理在程序規模稍大時就必定无法胜任.,代理机制,JDK动态代理Java在JDK 1.3之后加入协助开发动态代理功能的类,我們不必为特定对象与方法写特定的代理,使用动态代理,可以使得一个handler服务于各个对象,首先,一個handler必须实现java.lang.reflect.InvocationHandler,代理机制,JDK动态代理import java.lang.reflect.*;public class LogHandler implements InvocationHandler/private Object targetObject;/被代理的对象public Object createProxy(Object targetObject)/传入被代理的对象this.targetObject=targetObject;return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);/this通过被代理的对象生成它的代理对象,并同handler绑定在一起,代理机制,JDK动态代理public Object invoke(Object proxy,Method method,Object args)throws Throwable Object result=null;try System.out.println(begin);/日志记录result=method.invoke(targetObject,args);/!调用被代理对象的方法System.out.println(ok,end);/日志记录 catch(Exception e)e.printStackTrace();return result;InvocationHandler的invoke()方法会传入代理对象的方法名称与参数,实际上要执行的方法交由method.invoke(),並在其前后加上记录动作,method.invoke()返回的对象是实际方法执行过后的回传結果。,代理机制,JDK动态代理必須有接口:public interface IHello public void hello(String name);实现该接口:public class HelloSpeaker implements IHello public void hello(String name)System.out.println(Hello,+name);执行:加日志(利用代理类):LogHandler logHandler=new LogHandler();IHello helloProxy=(IHello)logHandler.createProxy(new HelloSpeaker();/传入被代理对象,传回代理对象helloProxy.hello(“焦学理);/-logHandler.invoke()-helloSpeaker.hello()执行:不加日志(不利用代理类):IHello h=new HelloSpeaker();h.hello(焦学理);,代理机制,JDK动态代理LogHandler不再服务于特定对象与接口,而HelloSpeaker也不用插入任何有关于日志记录的动作,它不用意识到日志记录动作的存在。上面例子中,如果HelloSpeaker本身插入日志记录动作,这使得HelloSpeaker的职责加重,並混淆其原來的角色,为此,使用代理将日志记录的动作提取出來,以分清日志记录的动作与HelloSpeaker的职责与角色。在这里,日志记录这个动作是我們所关注的,AOP中的Aspect所指的就是象日志记录这类的动作,将这些动作(或特定职责)视为关注的中心,将其设计为通用、不介入特定对象、职责清楚的组件,這就是所谓的面向Aspect。,代理机制,CGLib动态代理当代理对象没有实现接口,我们就可以 使用CGLIB生成代理,需要我们使用 cglib-nodep-2.1_3.jar。我们编写CGlibProxyFactory实例,需要实现 MethodInterceptor 接口publicclassCGLIBProxyimplementsMethodInterceptor privateObjecttargetObject;/代理的目标对象 publicObjectcreateProxyInstance(ObjecttargetObject)this.targetObject=targetObject;Enhancerenhancer=newEnhancer();/该类用于生成代理对象 enhancer.setSuperclass(this.targetObject.getClass();/设置父类 enhancer.setCallback(this);/设置回调用对象为本身 returnenhancer.create();publicObjectintercept(Objectproxy,Methodmethod,Objectargs,MethodProxymethodProxy)throwsThrowable returnmethodProxy.invoke(this.targetObject,args);CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。,代理机制,测试CGlibProxyFactoryfactory=newCGlibProxyFactory();PersionServiceBeanservice=(PersionServiceBean)factory.createProxyIntance(newPersionServiceBean();service.save(999);PersionServiceBean类没有实现接口,可以使用CGLib产生代理对象,这个代理对象是其子类实例。然后执行业务方法测试。总结:JDK动态代理:需要代理的对象要实现接口,代理对象要实现 InvocationHandler 接口使用CGLIB生成代理:需要代理的对象可以不用实现接口,代理对象要实现 MethodInterceptor 接口,基本概念,AOP中几个关键的概念:切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。连接点(Joinpoint):在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总是表示一个方法的执行。通知(Advice):在切面的某个特定的连接点上执行的动作。其中包括了“around”、“before”和“after”等不同类型的通知(通知的类型将在后面部分进行讨论)。(在JointPoint上所采取的动作,许多AOP框架通常以interceptor來实现Advice)切入点(Pointcut):匹配连接点的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。目标对象(Target Object):被一个或者多个切面所通知的对象。织入(Weaving):把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。,基本概念,通知类型:前置通知(Before advice):在某连接点之前执行的通知。后置通知(After returning advice):在某连接点正常完成后执行的通知。异常通知(After throwing advice):在方法抛出异常退出时执行的通知。最终通知(After(finally)advice):当某连接点退出的时候执行的通知。环绕通知(Around Advice):包围一个连接点的通知,LogHandler在hello()这个JointPoint上会调用Around Advice。事务处理调用的Advice也是属于Around Advice,Thank You!,