转载《Spring AOP》

来源:互联网 发布:宾得k 1 知乎 编辑:程序博客网 时间:2024/04/30 02:25

AOP是Aspect Oriented Programming的缩写,意思是面向方面编程,一种新兴的编程技术。
AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,
AOP可以说也是这种目标的一种实现。它可以解决OOP和过程化方法不能够很好解决的横切
(crosscut)问题,
如:事务、安全、日志等横切关注。当未来系统变得越来越复杂,
横切关注点就成为一个大问题的时候,AOP就可以很轻松的解决横切关注点这个问题。

比如有这样一个情景:


Java代码

这个例子虽然是很好的面向对象代码,但是在业务处理逻辑中夹杂这日志处理和权限判断,变得复杂混乱.
在 AOP 中,正交关注点(如安全和日志记录)被识别为系统中的常见横切关注点。说它们是横切,
是因为它们总是切入模块(如包、类和代码文件)的多个单位。也许横切关注点可能不是核心业务逻辑的一部分,但是它们是应用程序的基本部分。

AOP的实现主要是通过方法的拦截实现.在不使用AOP框架的情况下,我们可以通过JDK提供的动态代理来实现方法的拦截

注意:使用JDK提供的动态代理实现
要求我们的目标对象必须实现接口

IUserBean接口

Java代码

IUserBean实现类 UserBean.java

Java代码

我们希望在UserBean执行方法之前先检查userName是不是为空,以此做为权限判断.
当然我们可以在没个方法里面去加这些判断,但是这需要为每个方法都添加同样的判断,维护不便.
使用JDK提供的动态代理技术可以很方便的实现上面的需求:
通过java.lang.reflect.Proxy;提供的
public static Object newProxyInstance(ClassLoader loader,
  Class<?>[] interfaces,
  InvocationHandler h)

方法可以生成一个动态代理对象
其中
loader是类装载器
interfaces是目标对象实现的一系列接口
h是一个实现InvocationHandler接口的类,我们对代理对象的所有操作都经过它处理
这样我们就可以拦截到UserBean的方法,在方法执行前先判断是否有权限,如果有则执行方法,
没有权限的话就不执行方法.

编写我们的代理类:
JDKProxy.java

Java代码

通过调用createProxyObject可以生成代理对象,
编写测试类如下:


Java代码

执行成功后输出:
this is addUser() method!

再次修改测试类:


Java代码

即当用户没有权限时,控制台不输出东西,说明我们拦截方法对其做的权限判断生效了.

从上面这个例子可以成功拦截了调用的方法并对其做了相应的处理

如果不使用JDK提供的Proxy类
通过cglib创建代理类,好处是不要求我们的目标对象实现接口
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());

enhancer.setCallback(this); //回调,参数是一个实现MethodInterceptor接口的类,我们对代理对象的所有操作都经过它处理
return enhancer.create(); //创建代理对象


修改UserBean 去掉IUserBean接口


Java代码

通过cglib创建代理类

CGLibProxy.java

Java代码

编写测试类:

Java代码 
 


输出:
this is addUser() method!

当取消用户权限时,控制台不输出任何东西.

说明通过CGLib成功生成代理对象,拦截了目标对象的方法.


Spring主要通过代理来实现AOP

下面是AOP的一些基本概念:

切面(Aspect):对横切关注点的抽象(类似类对对象的抽象)

连接点(JoinPoint):被拦截到的点,泛指方法

切入点(CutPoint):对哪些连接点进行拦截的定义

通知(Advice):在特定的连接点,AOP框架执行的动作.前置/后置/例外/最终/环绕通知(调用方法之前执行,全部执行完毕之后)

引入(Introduction): 添加方法或字段到被通知的类。 Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现 IsModified接口,来简化缓存。

目标对象(Target Object): 包含连接点的对象。也被称作 被通知或被代理对象。

AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。

织入(Weaving): 组装方面来创建一个被通知对象。这可以在编译时 完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样, 在运行时完成织入。

Adive通知可理解如下:

Java代码

Spring提供两种方式实现AOP
一种是XML配置的方式
一种是annotation注解的方式

不管采用哪种方式,都必须在spring的配置文件中配置AOP支持:

Xml代码 
 


其中<aop:aspectj-autoproxy/>表示打开aspect注解处理器
(aspect的内容具体可查看http://www.ibm.com/developerworks/cn/java/j-aspectj/)

使用注解方式实现AOP必须引入三个jar包:
aspectjweaver.jar
aspectjrt.jar
cglib.jar

首先建立好测试用的业务bean
然后我们需要定义一个切面/定义切入点/通知等

接口IUserBean.java

Java代码

实现类UserBean.java

Java代码

紧接着我们建立我们的切面类:使用@Aspect注解
MyInterceptor.java

Java代码

切面定义好之后我们必须交给Spring管理,配置我们的bean.xml文件如下:

Xml代码

编写测试类如下:

Java代码

运行测试类输出:
前置通知
进入方法
this is addUser() method!
后置通知
最终通知
退出方法

可以看出定义的各个通知的执行顺序,
例外通知只有在程序异常的情况下才会发生.
其他通知都会执行.
我们也可以在环绕通知里面将前面的几个通知实现了.

如果需要获取方法的参数我们必须在定义通知的时候做响应的设置:
比如我在前置通知希望获取到输入的参数需要修改MyInterceptor如下:

Java代码

重新运行测试类输出:

前置通知royzhou
进入方法
this is addUser() method!
后置通知
最终通知
退出方法

可见我们成功的获取到了方法的参数


如果需要获取方法的返回值,则修改如下:

Java代码

输出结果是:

前置通知1
进入方法
this is getUser() method!
后置通知haha
最终通知
退出方法

可见方法的返回值我们也成功拿到了.

如需在例外通知中获取例外的详细信息,我们只需要配置:

Java代码

上面的例子介绍了使用注解方式来实现Spring的AOP
另外我们可以使用XML来配置:

使用XML配置Spring的AOP 我们的切面类MyInterceptor不需要做任何注解,就是一个普通的Java类


Java代码

接下来我们需要在bean.xml文件中配置我们的切面/切入点/通知等信息


Xml代码

注意在前置通知中不支持args-name指定参数,必须在pointcut中指定,否则服务器抛出异常:0 formal unbound in pointcut

总结一下AOP的优点:
面对方法编程并不是要取代面对对象编程,而是要提高它。AOP程序员一般来说都是90%使用OOP来解决问题,而10%是用AOP来解决OOP不能解决的问题。

横切关注点(Cross-cutting Concerns)
  很多时候你发现你的类并不能十分清晰和明白的表到你所想表达的功能意义,因为你真正的代码
  大多被其它代码所包围了。如果你想很好的扩展或集成你所想表达的功能意义,你最好就用方面
  的思想来考虑它了。

开发中的分层(Layering Based on Deployment)  
    AOP另外一个很有用的地方就是可以用来为你的应用程序分层。很多时候你希望的一些特殊应用或
  类是可以很好的配置的,但同时也希望这些东西是不臃肿和可以扩展的。AOP提供了很好的途径来
  分层这些复杂的东西。JBOSS AOP提供了XML配置的机制来配置每个方面的开发。最好的例子就是
  缓存服务,它提供了不同的锁机制。这些缓存锁机制可以很好的织入你的类,而不影响你的类的
  代码,这样你的类就是很好的扩展性了。

透明性(Transparency)
  很多时候你都想把你的程序的焦点集中在商务应用和应用逻辑上,而不是关注于中间件的开发。
  AOP允许你透明的应用中间件而不再使你的代码收到污染。一个很好的例子就是JBOSS AOP中的
  用户认证上面。

异常处理
  处理异常是AOP提供给我们另外一个很有用的东西。例如,SQLException异常包含了SQL语句的
  异常信息或者数据库的死锁等信息,但这些信息却使用不同错误代码和信息。AOP可以让你拦截
  SQL语句信息,并分类处理数据库死锁信息。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/hello_zhenyu/archive/2009/10/07/4639413.aspx

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝和手机不兼容怎么办 换号之后微信怎么办 手机不兼容的应用程序怎么办 微信版本低登录不了怎么办 软件与系统不兼容怎么办 软件与手机系统不兼容怎么办 qq和手机不兼容怎么办 来个软件不兼容怎么办 安卓8.0不兼容app怎么办 两条内存不兼容怎么办 王者荣耀软件不兼容怎么办 冒险岛不兼容win7怎么办 百度网盘手机号换了怎么办 破解版游戏闪退怎么办 安卓手机软件不兼容怎么办 安卓8.0软件闪退怎么办 游戏与手机系统不兼容怎么办 耳机和手机不兼容怎么办 软件和手机不兼容怎么办 小米6开关键失灵怎么办 同步助手下载不了微信旧版本怎么办 闲鱼退货卖家拒收怎么办 闲鱼把联系人删了怎么办 闲鱼付款了卖家不发货怎么办 红米4c卡怎么办 如果买鞋子买到假的怎么办 猎趣永久封号钱怎么办 支付宝换绑定手机后怎么办 为什么回收站的删除键不见了怎么办 微信在异地登录怎么办 支付宝帐号被冻结怎么办 进不了路由器设置页面怎么办 支付宝支付密码忘记了怎么办 淘宝忘记登录密码了怎么办 手机换卡了微信怎么办 淘宝退款成功后收到货怎么办 没收到货退款商家不处理怎么办 没收到货申请退款卖家不处理怎么办 京东已收到货却不处理退款怎么办 货退了卖家不退款怎么办 淘宝退了货卖家不退款怎么办