转载《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
- 转载《Spring AOP》
- 转载《Spring AOP》
- [转载]Spring AOP
- Spring AOP 详解【转载】
- spring aop实例(转载)
- Spring AOP 详解(转载)
- spring AOP概念理解(转载)
- Spring AOP进行日志记录(转载)
- Spring AOP 学习小结---转载自ITeye
- 转载:理解Spring OC 与& AOP 的
- 【转载】基于@AspectJ配置Spring AOP之一
- 【转载】spring aop 三种实现方式示例
- Spring IoC与AOP的核心思想(转载)
- 基于注解的Spring AOP的配置和使用--转载
- 基于注解的Spring AOP的配置和使用--转载
- Spring IoC与AOP的核心思想(转载)
- 基于注解的Spring AOP的配置和使用--转载
- 基于注解的Spring AOP的配置和使用--转载
- Vi技巧
- 优酷网视频存储架构
- 生产者消费者问题之Java线程实现
- Lesson 9 Flying cats 飞猫
- ASP.NET获取服务器信息
- 转载《Spring AOP》
- 用SELECT复制记录和表
- 嵌入式系统引导技术研究
- 恐怖
- 关于我上传的资源!!
- 网络游戏需要辅助性外挂?
- SPSS Clementine 数据挖掘入门
- Windows UI常用函数
- Lesson 10 The loss of the Titanic “泰坦尼克“号的沉没