《Spring AOP学习总结之——通过动态代理实现AOP功能》
来源:互联网 发布:团队复制优化方案 编辑:程序博客网 时间:2024/06/05 12:07
代理设计模式的原理:使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
demo示例:
实现计算器的算法计算,如果是添加方法,则记录方法的基本日志,其它方法都一律不记录日志。
Demo示意图:
Demo实现:
1·计算器接口:
package com.dynamic.aop.helloworld;/** * 实现基本计算器的算术计算 * @author 贾丽敏 * */public interface ArithmeticCalculator {public int add(int i,int j);public int sub(int i,int j);public int mul(int i,int j);public int dev(int i,int j);}2·计算器接口实现类:
package com.dynamic.aop.helloworld;/** * 计算器接口实现类 * @author 贾丽敏 * */public class ArithmeticCalculatorImpl implements ArithmeticCalculator {public int add(int i, int j) {int result =i+j;return result;}public int sub(int i, int j) {int result =i-j;return result;}public int mul(int i, int j) {int result =i*j;return result;}public int dev(int i, int j) {int result =i/j;return result;}}3·模拟日志的控制:
package com.dynamic.aop.helloworld;import java.lang.reflect.Method;import java.util.Arrays;/** * 定义日志切面 * @author 贾丽敏 * */public class LoggingAspect {public static void beginLogging(Method method,Object[] obj){System.out.println("the method "+ method.getName()+" begins with " + Arrays.asList(obj));}public static void endLogging(Method method,Object obj){System.out.println("the method "+ method.getName()+" end with " + Arrays.asList(obj));System.out.println("------------------华丽的分界面--------------------");}}
4·通过动态代理实现动态切入:
package com.dynamic.aop.helloworld;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * 通过动态代理实现切入 * @author 贾丽敏 * */public class ArithmeticCalculatorProxy {private ArithmeticCalculator target;public ArithmeticCalculatorProxy(ArithmeticCalculator target) {super();this.target = target;}public ArithmeticCalculator getLoggingProxy(){ArithmeticCalculator proxy=null;//代理对象由哪一个类加载器负责加载ClassLoader loader=target.getClass().getClassLoader();//代理对象的类型,即其中有哪些方法Class[] interfaces=new Class[]{ArithmeticCalculator.class};InvocationHandler h=new InvocationHandler() {/** * proxy:正在返回的那个代理对象,一般情况下,在invoke方法中都不是用该对象 * method:被代理类(目标类)的方法 * args:调用被代理类(目标类)方法时,传入的参数 */public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {String methodName=method.getName();if (methodName.equals("add")){//如果调用目标方法名称为“add”则进行拦截//方法之前记录日志LoggingAspect.beginLogging(method,args);Object result=method.invoke(target, args);//调用目标类的目标方法//方法之后记录日志LoggingAspect.endLogging(method,result);return result;}else{Object result=method.invoke(target, args);//调用目标类的目标方法return result;}}};proxy=(ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);return proxy;}}
5·测试类:
package com.dynamic.aop.helloworld;import org.junit.Test;/** * 测试动态代理实现AOP切入 * @author 贾丽敏 * */public class test {@Testpublic void test() {ArithmeticCalculator target= new ArithmeticCalculatorImpl();ArithmeticCalculator proxy=new ArithmeticCalculatorProxy(target).getLoggingProxy();int result=0;result=proxy.add(1, 3);result=proxy.sub(5, 2);}}
6·执行结果:(满足条件的add方法添加了日志,sub方法则没有被拦截进行日志的记录)
Demo分析:
以上demo中,通过动态代理实现AOP的动态切入,我认为有以下几个关键点:
1·在客户端调用目标方法时,并不知道该方法是否要进行的日志的记录,也就是说目标类ArithmeticCalculator和日志记录类LoggingAspect之间并没有任何的关系。是代理类在中间起到了连接作用。
2·拦截器的存在很关键:拦截器体现了AOP的"动态切入",执行代理类的方法时,拦截器实现了:在一定的条件下,对方法进行日志的记录。
Demo引发的思考:
1·拦截器的invoke方法在时候被调用的?
在客户端调用目标类的方法时,其实是调用的代理类的方法,当执行代理类的方法时执行了拦截器的invoke方法。
2·这个和Spring核心AOP有什么关系?
AOP的核心就是面向切面编程,即动态切入从而达到代码的灵活可用性。且AOP实现动态切入的核心就是动态代理。
Demo基本概念小总:
这其实就是AOP中一些所谓的“晦涩难懂”的基本概念而已。
先来看张图片(灵感来自于一篇朋友的博客《springAOP的基本概念》)
目标类:就是我们需要完成的基本功能的类,就像上面例子中的ArithmeticCalculator。
目标方法:就是目标类中的方法
切面(Aspect):就是和正常的业务逻辑无关的代码,像LoggingAspect
通知(Advice):切面中的方法就是通知
连接点(Join point):在客户端调用目标类的那个方法,那个方法就是连接点。
切入点(PointCut):对目标类方法进行日志记录的条件:就是什么情况下才能让通知和目标方法结合在一起
织入(Weaving):形成代理对象的过程就是织入;
这是自己初步的AOP的总结,之前的理解总是感觉有点浅显,如今再次回顾,同时借助于一个朋友的两篇博客,突然有一种很是简单的感觉。
接下来的系列博客正在编辑中,请多多支持。
- 《Spring AOP学习总结之——通过动态代理实现AOP功能》
- 《Spring AOP学习总结之二—XML配置实现AOP功能》
- Spring AOP 学习之cJlib动态代理
- Spring动态代理,aop 注解实现aop
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
- 动态代理实现Spring Aop
- Spring AOP之动态代理
- Spring 容器AOP的实现原理——动态代理
- Spring 容器AOP的实现原理——动态代理
- Spring AOP的实现——动态代理机制
- Spring 容器AOP的实现原理——动态代理
- spring的AOP学习2——动态代理
- Spring学习(1)AOP初步—JDK动态代理
- 《Spring AOP学习总结之四—AOP实现读写分离》
- Spring AOP——Java动态代理
- 《Spring AOP入门——动态代理》
- Spring AOP基础—JDK动态代理
- PHP4 PDO
- C++ CLI简介(什么是C++ CLI)
- 工作设置内存与内存专用工作集 区分
- VLC做RTSP服务器,自己写客户端与服务器命令交互demo
- form表单提交后不刷新不跳转
- 《Spring AOP学习总结之——通过动态代理实现AOP功能》
- [编程题] 下厨房
- 一、Eclipse 的 maven插件 安装 和配置
- php结合redis实现高并发下的抢购、秒杀功能
- C ++ Primer Plus 第六版 第十二章编程练习答案
- Android在应用内启动另一个应用程序apk的两种方式
- Tokyo Cabinet
- jQuery JavaScript的综合性UI组件库jQWidgets更新至v5.0.0丨附下载
- 设计一套好的RESTful API