关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » JAVA »手把手教你用Java实现AOP

    手把手教你用Java实现AOP

    2015-03-29 00:00:00 出处:codeceo
    分享

    介绍

    众所周知,AOP(面向切面编程)是Spring框架的特色功能之一。通过设置横切关注点(cross cutting concerns),AOP提供了极高的扩展性。那AOP在Spring中是怎样运作的呢?当你只能使用core java,却需要AOP技术时,这个问题的解答变得极为关键。不仅如此,在高级技术岗位的面试中,此类问题也常作为考题出现。这不,我的朋友最近参加了一个面试,就被问到了这样一个棘手的问题——如何在不使用Spring及相关库,只用core Java的条件下实现AOP。因此,我将在ITJS的这篇文章中提供一份大纲,帮助大家了解如何只用core Java实现一个AOP(当然啦,这种AOP在功能上有一定的局限性)。注意,ITJS的这篇文章不是一篇有关Spring AOP与Java AOP的对比研究,而是有关在core Java中借助固有的设计模式实现AOP的教程。

    想必读者已经知道AOP是什么,也知道在Spring框架中如何使用它,因此ITJS的这篇文章只着眼于如何在不用Spring的前提下实现AOP。首先,我们得知道,Spring是借助了JDK proxy和CGlib两种技术实现AOP的。JDK dynamic proxy提供了一种灵活的方式来hook一个方法并执行指定的操作,但执行操作时得有一个限制条件:必须先提供一个相关的接口以及该接口的实现类。实践出真知,让我们透过一个案例来理解这句吧!现在有一个计算器程序,用于完成一些数学运算。让我们来考虑下除法功能,此时的问题是:如果core framework 已经具备了一份实现除法的代码,我们能否在代码执行时劫持(highjack)它并执行额外的校验呢?答案是肯定的,我将用下面提供的代码片段来证明这点。首先来看基础接口的代码:

     public interface Calculator {
        public int calculate( int a , int b);
    }

    该接口实现类的代码如下:

     public class CalculatorImpl implements Calculator {
        @Override
        public int calculate(int a, int b) {
            return a/b;
        }
    }

    假设我们既不能修该上面的代码,也不能对核心库进行任何改动,怎样才能完美地实现校验功能呢?不如试下JDK dynamic proxy的功能吧。

    public class SomeHandler implements InvocationHandler {
    
    // Code omitted for simplicity…..
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
    // Your complex business validation and logic
            Object result = method.invoke(targetObject ,params);
            return result;
        }
    
    }

    让我们通过测试类来看看由JDK dynamic proxy实现的校验功能的效果如何。

    public static void main(String[] args) {
            CalculatorImpl calcImpl = new CalculatorImpl();
            Calculator proxied = (Calculator)ProxyFactory.getProxy (Calculator.class, calcImpl, 
                    new SomeHandler(calcImpl));
            int result = proxied.calculate(20, 10);
            System.out.println("FInal Result :::" + result);
        }

    从结果可以看出,简单地实现功能强大的InvocationHandler接口,我们便能得到一个hooking implementation。按照JDK文档的描述,InvocationHandler接口是借助一个代理实例(proxy instance)来处理一个方法调用的。

    现在我们已经知道,InvocationHandler的invoke()方法能够帮助我们解决问题。那么再来解决一个新问题——怎样才能在方法执行的前后执行操作呢?说的更具体一些,我们能通过添加多个aop(before、after、around)来hook一个方法吗(译注:原文为add multiple aops,但我认为Handler是充当Aspect的角色)?答案同样是肯定的。按照以下的步骤建立一个精简的代码模板便能满足这样的需求:

    创建一个抽象类,用于将aop应用于目标对象上。 创建名为BeforeHandler 和 AfterHandler的两个aop。前者在方法执行之前工作,而后者则在方法执行结束后工作。 创建一个代理类,使所有的aop handler和目标对象只需作为参数传入,就能创建一个hook。 加入你自己的业务逻辑或者横切关注点。 最后,通过传入相关的参数创建代理对象(proxy object)。

    技术实现概要

    (译注:此处是核心代码片段,如果想运行该实例,需进入下方提供的链接下载完整代码)

    创建一个handler的抽象类:

    public abstract class AbstractHandler implements InvocationHandler {
    
    	private Object targetObject;
    
    	public void setTargetObject(Object targetObject) {
    		this.targetObject = targetObject;
    	}
    }

    创建名为BeforeHandler和AfterHandler的两个易扩展的handler抽象类:

    public abstract class BeforeHandler extends AbstractHandler {
    	public abstract void handleBefore(Object proxy, Method method, Object[] args);
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		handleBefore(proxy, method, args);
    		return method.invoke(getTargetObject(), args);
    	}
    }
    public abstract class AfterHandler extends AbstractHandler {
    	public abstract void handleAfter(Object proxy, Method method, Object[] args);
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		Object result = method.invoke(getTargetObject(), args);
    		handleAfter(proxy, method, args);
    		return result;
    	}
    }

    创建Proxy的工厂类:

    public class ProxyFactory {
    
    	public static Object getProxy(Object targetObject,
    			List handlers) {
    			//Code to get the proxy
    			return proxyObject;
    		} else {
    			return targetObject;
    		}
    	}
    }

    以下为测试代码:

    CalculatorImpl calcImpl = new CalculatorImpl();
    BeforeHandler before = new BeforeHandlerImpl();
    AfterHandler after = new AfterHandlerImpl();
    List<AbstractHandler> handlers = new ArrayList<AbstractHandler>();
    handlers.add(before);
    handlers.add(after);
    Calculator proxy = (Calculator) ProxyFactory.getProxy(calcImpl,
    				handlers);
    int result = proxy.calculate(20, 10);

    配置

    以上的代码片段简明扼要地解释了AOP在结构上的实现(structural implementation)。当然,如果能通过实际的测试将其运用到现实中去,那就再好不过了。读者可在下面的链接中获取完整的工程文件,并在Java编辑器中配置它们,最后通过其中的测试类来检验效果。

    https://github.com/debjava/aopusingjdkdynamicproxy

    总结

    希望这篇简短的有关AOP文章能够帮助到大家。需说明的是,ITJS的这篇文章只实现了before和after两种aop,而另外两种,即“Around”和“Throw”,则希望读者自行完成。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    商业智能成CIO优先关注点 技术落地方显成效(1)

    用linux安装MySQL时产生问题破解

    JAVA中关于Map的九大问题

    windows 7旗舰版无法使用远程登录如何开启telnet服务

    Android View 事件分发机制详解

    MySQL用户变量的用法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。