您的位置:首页 > 编程语言 > Java开发

代理模式与spring的AOP

2015-10-19 11:48 288 查看
JAVA的代理模式

代理模式是常用的java设计模式.

代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者

不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用.

特征是代理类与委托类有同样的接口代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等

代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的 对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来

提供特定的服务。

分为:

抽象主题角色:声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题的地方都可以是使用代理主题

代理主题(Proxy)角色:代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可


以在任何时候都可以替代真实主题控制对真实主题的引用,负责在需要的时候创建真实主题对象(和删除真实主题对象);代理角色通常在将客户端调用传递给真实的主题

之前或之后,都要执行某个操作,而不是单纯地将调用传递给真实主题对象。

真实主题角色:定义了代理角色所代表地真实对象



按照代理的创建时期,代理类可以分为三种:

静态代理:

由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

特点:

1.必须有接口



2.代理类只能用在定义好的一个接口里面



3.如果有n个接口,写n个实现,n个代理类



4.必须修改调用方

JDK动态代理:在程序运行时,运用反射机制动态创建而成。Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。

特点:

1.必须要有接口



2.业务方法的调用必须通过代理对象调用

CGLIB代理:

1.CGLIB(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。

2.CGLIB封装了asm,可以在运行期动态生成新的class。

3.CGLIB用于AOP,jdk中的proxy必须基于接口,CGLIB却没有这个限制,但是目标类不能为final,因为它基于动态创建子类

特点:

1.可以对没有接口的类,进行代理(此类不能是final类)



2.业务方法的调用必须通过代理对象调用

区别:

java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加

载进来,通过修改其字节码生成子类来处理。

使用代理的选择:

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP



2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP



3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

4、CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强

spring里面的aop就是代理模式实现

Spring有两种代理方式:

建议使用:



1.若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理。

2.若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。

添加cglib的jar文件

net.sourceforge.cglib\com.springsource.net.sf.cglib\2.2.0

com.springsource.net.sf.cglib-2.2.0.jar

使用该方式时需要注意:

1.对接口创建代理优于对类创建代理,因为会产生更加松耦合的系统。

对类代理是让遗留系统或无法实现接口的第三方类库同样可以得到通知 (这种方式应该是备用方案)

2.标记为final的方法不能够被通知。spring是为目标类产生子类。任何需要

被通知的方法都被复写,将通知织入。final方法是不允许重写的。



只有在配置文件里面配置了aop增强的功能,不用修改源代码,也不用修改调用方,就把功能增强
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: