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

——java动态代理及AOP

2014-07-31 21:54 218 查看
代理的概念及作用

代理模式的概念:

为其他对象提供一种代理以控制对这个对象的访问。

说白了就是,在一些情况下客户不想或者不能直接引用一个对象,

而代理对象可以在客户和目标对象之间起到中介作用,去掉客户不能看到的内容和服务或者增添客户需要的额外服务。

生活中的代理:

一,买东西可以从代理商那里买,也可以从厂商那里卖。

但目的都是要得到商品。从代理商那里买显然更方便。

程序中的代理:

1,要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能

例如,异常处理,日志,计算方法的运行时间,事务管理等等。。

2,编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类

的相同方法,并在调用方法时加上系统功能的代码(参见原理图)

原理图:

3,如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,

在配置文件中配置使用用的目标类,还是代理类。这样可以很容易切换,

譬如,想要日志功能时就配置代理类,否则配置目标类,这样,增加系统功能很容易

以后运行一段时间后,又想去掉系统功能也很容易。

AOP(Aspect Orlented Program 即:面向方面编程,简称AOP):

什么是AOP?

将一切实物都抽象的看做是多个实体的抽象体,而每个不同类型的抽象体都能够作为这个实物的一种实现机制的表现,

从而在业务拓展时减少对原有代码的维护,取而代之的则是 增加->切换 的操作。

AOP的优势:

相对于OOP,面向AOP更具有可拓展性和高维护性的优势。

具体表现在:以往我们都以“世界万物皆对象”的思想进行编程时,会将一切事物抽象成一个实体,并使用这个实体进行我们业务方面的拓展。

一,系统中存在交叉业务,一个交叉业务就是要切入到系统中的一个方面:

如下所示:

安全 事务 日志

StudentService-----|-------|-------|----

CurseService -----|-------|-------|----

MiscService -----|-------|-------|----

二,用具体程序代码描述交叉业务:

method
method method

{ { {

-----------------------------切面

。。。
。。。 。。。

-----------------------------切面

} } }

三,交叉业务的编程问题即为面向方面的编程(Aspect Orlented Program 简称AOP),

AOP的目标就是要是交叉业务模块。可以采用切面代码移动到原始方法的周围,这与直接在方法

中编写切面代码的运行效果是一样的。

如下所示:

-----------------------------切面

func1
func2 func3

{ {{

...
... ...

} }}

-----------------------------切面

四,使用代理技术正好可以解决这种问题,代理是实现AOP功能的核心和关键技术。

动态代理技术

一,要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理的方式,

是一件很麻烦的事情。

二,JVM可以在运行时动态的生成出类的字节码,这种动态生成的字节码问问被用作代理类,及动态代理类。

三,JVM生成的动态类必须实现一个或多个接口。所以JVM生成的动态类只能用作具有相同接口的目标类的代理。

四,CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现

接口的类生成动态代理类,那么可以使用CGLIB库。

五,代理类的各种方法中通常除了药调用目标类的相应方法和队伍返回目标返回结果外,还可以在代理方法中的

如下四个位置加上系统功能代码:

1,在调用目标方法之前

2,在调用目标方法之后

3,在调用目标方法前后

4,在处理目标方法异常的catch块中

分析JVM动态生成的类

一,创建实现了Collection接口的动态类和查看其名称,分析Proxy.getProxyClass方法的更改参数。

二,编码列出动态类中的所有构造方法和参数签名

三,编码列出动态类中的所有方法和参数签名

四,创建动态的实例对象

1,用反射获得构造方法

2,编写一个最简单的InvocationHandler接口的实现类

3,调用构造方法创建动态类的实例对象,并将编写的InvocationHandler实现类的对象传进去。

4,打印创建的对象和调用对象的没有返回值的方法很getClass方法,演示调用其他方法没有返回值报出异常

5,将创建动态类的实例对象的代理改成匿名内部类的形式编写。

让JVM创建动态类,需要给它提供如下信息:

三个方面:

1,生成的类中有哪些方法,通过让其实现哪些接口的方式进行告知;

2,产生的字节码必须有一个关联的类加载器对象

3,生成的类中的方法代码是怎么样的,也是自定义的,把我们的代码写在一个约定好了接口对象的方法中。

把对象传给它,它调用自定义的方法,相当于插入了自定义的代码,提供执行代码的对象就是那个InvocationHandler

对象,它是在创建动态类的实例对象的构造方法时传递进去的,在上面的InvocationHandler对象的invoke得到中加了

一些代码,就可以看到执行代码被调用运行了。

也可以用Proxy.newInstance方法直接一步就创建出代理对象。

完整的实例代码如下:

用到的自定义接口及类:

自定义的Advice接口:

Advice接口的实现类:

自定义的接口:

自定义的接口的实现类:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: