Java实现AOP面向切面编程的实例教程_第1页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Java实现AOP面向切面编程的实例教程这篇文章主要介绍了Java实现AOP面向切面编程的实例教程,通常Java中的AOP都是利用Spring框架中造好的轮子来开发,而本文则关注于Java本身AOP的设计模式实现,需要的朋友可以参考下介绍 众所周知,AOP(面向切面编程)是Spring框架的特色功能之一。通过设置横切关注点(cross cutting concerns),AOP提供了极高的扩展性。那AOP在Spring中是怎样运作的呢?当你只能使用core java,却需要AOP技术时,这个问题的解答变得极为关键。不仅如此,在高级技术岗位的面试中,此类问题也常作为考题出现。这不,我的朋友最近参

2、加了一个面试,就被问到了这样一个棘手的问题如何在不使用Spring及相关库,只用core Java的条件下实现AOP。因此,我将在本文中提供一份大纲,帮助大家了解如何只用core Java实现一个AOP(当然啦,这种AOP在功能上有一定的局限性)。注意,本文不是一篇有关Spring AOP与Java AOP的对比研究,而是有关在core Java中借助固有的设计模式实现AOP的教程。 想必读者已经知道AOP是什么,也知道在Spring框架中如何使用它,因此本文只着眼于如何在不用Spring的前提下实现AOP。首先,我们得知道,Spring是借助了JDK proxy和CGlib两种技术实现AOP

3、的。JDK dynamic proxy提供了一种灵活的方式来hook一个方法并执行指定的操作,但执行操作时得有一个限制条件:必须先提供一个相关的接口以及该接口的实现类。实践出真知,让我们透过一个案例来理解这句吧!现在有一个计算器程序,用于完成一些数学运算。让我们来考虑下除法功能,此时的问题是:如果core framework 已经具备了一份实现除法的代码,我们能否在代码执行时劫持(highjack)它并执行额外的校验呢?答案是肯定的,我将用下面提供的代码片段来证明这点。首先来看基础接口的代码:public interface Calculator public int calculate( i

4、nt 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 pub

5、lic 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

6、 CalculatorImpl(); Calculator proxied = (Calculator)ProxyFactory.getProxy (Calculator.class, calcImpl, new SomeHandler(calcImpl); int result = calculate(20, 10); System.out.println(FInal Result : + result); 从结果可以看出,简单地实现功能强大的InvocationHandler接口,我们便能得到一个hooking implementation。按照JDK文档的描述,InvocationHan

7、dler接口是借助一个代理实例(proxy instance)来处理一个方法调用的。 现在我们已经知道,InvocationHandler的invoke()方法能够帮助我们解决问题。那么再来解决一个新问题怎样才能在方法执行的前后执行操作呢?说的更具体一些,我们能通过添加多个aop(before、after、around)来hook一个方法吗(译注:原文为add multiple aops,但我认为Handler是充当Aspect的角色)?答案同样是肯定的。按照以下的步骤建立一个精简的代码模板便能满足这样的需求: 1.创建一个抽象类,用于将aop应用于目标对象上。2.创建名为BeforeHand

8、ler 和 AfterHandler的两个aop。前者在方法执行之前工作,而后者则在方法执行结束后工作。3.创建一个代理类,使所有的aop handler和目标对象只需作为参数传入,就能创建一个hook。4.加入你自己的业务逻辑或者横切关注点。5.最后,通过传入相关的参数创建代理对象(proxy object)。 两种实现AOP的方式: 1,JDK提供的动态代理实现 接口 public interface UserBean void getUser(); void addUser(); void updateUser(); void deleteUser(); 原始实现类 public cla

9、ss UserBeanImpl implements UserBean private String user = null; public UserBeanImpl() public UserBeanImpl(String user) this.user = user; public String getUserName() return user; public void getUser() System.out.println(this is getUser() method!); public void setUser(String user) this.user = user; Sy

10、stem.out.println(this is setUser() method!); public void addUser() System.out.println(this is addUser() method!); public void updateUser() System.out.println(this is updateUser() method!); public void deleteUser() System.out.println(this is deleteUser() method!); 代理类 import java.lang.reflect.Invocat

11、ionHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.cignacmc.finance.bean.UserBeanImpl; public class UserBeanProxy implements InvocationHandler private Object targetObject; public UserBeanProxy(Object targetObject) his.targetObject = targetObject; public Object in

12、voke(Object proxy, Method method, Object args) throws Throwable UserBeanImpl userBean = (UserBeanImpl) targetObject; String userName = userBean.getUserName(); Object result = null; /权限判断 if(userName != null & !.equals(userName) result = method.invoke(targetObject, args); return result; 测试类 import ja

13、va.lang.reflect.Proxy; import com.cignacmc.finance.bean.UserBean; import com.cignacmc.finance.bean.UserBeanImpl; import xy.UserBeanProxy; public class ProxyExe public static void main(String args) System.out.println(Proved.); UserBeanImpl targetObject = new UserBeanImpl(Bob Liang); UserBeanProxy pro

14、xy = new UserBeanProxy(targetObject); /生成代理对象 UserBean object = (UserBean)Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), proxy); object.addUser(); System.out.println(NO Proved.); targetObject = new UserBeanImpl(); proxy = new UserBeanProxy(t

15、argetObject); /生成代理对象 object = (UserBean)Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), proxy); object.addUser(); 输出: Proved. this is addUser() method! NO Proved. 从上面这个例子可以成功拦截了调用的方法addUser()并对其做了相应的处理 2, 通过cglib创建代理类 好处是不要求我们的目标对象实现接口 原始类 p

16、ublic class ClientBean private String name = null; public ClientBean() public ClientBean(String name) = name; public void addClient() System.out.println(this is addClient() method!); public void deleteClient() System.out.println(this is deleteClient() method!); public void getClient() System.out.pri

17、ntln(this is getClient() method!); public void updateClient() System.out.println(this is updateClient() method!); public String getClientName() return name; public void setClientName(String name) = name; 代理类 import java.lang.reflect.Method; import com.cignacmc.finance.bean.ClientBean; import xy.Enha

18、ncer; import xy.MethodInterceptor; import xy.MethodProxy; public class CGLibProxy implements MethodInterceptor private Object targetObject; public Object createProxyObject(Object targetObject) this.targetObject = targetObject; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.targetObj

19、ect.getClass(); enhancer.setCallback(this); return enhancer.create(); public Object intercept(Object proxy, Method method, Object args, MethodProxy methodProxy) throws Throwable ClientBean clientBean = (ClientBean)targetObject; String userName = clientBean.getClientName(); Object result = null; if(userName != null & !.equals(userName) result = method.invoke(targetObject, args); return result; 测试类 import java.lang.reflect.Proxy; import com.cignacmc.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论