JAVA的动态代理机制和Spring的实现方式 不指定

Heck post in 编程杂谈 2014/03/30 14:40 评论(0) 阅读(1670) | |
JAVA 代理实现
代理的实现分动态代理和静态代理,静态代理的实现是对已经生成了的JAVA类进行封装。
动态代理则是在运行时生成了相关代理类,在JAVA中生成动态代理一般有两种方式。

JDK自带实现方法
JDK实现代理生成,是用类 java.lang.reflect.Proxy, 实现方式如下

Eg:



测试代理类方法


1、Proxy实现代理的目标类必须有实现接口

2、 生成出来的代理类为接口实现类,和目标类不能进行转换,只能转为接口实现类进行调用

明显特点:通过此方法生成出来的类名叫做 $Proxy0

用CGLIB包实现
CGLIB是一个开源项目,官方网址是:http://cglib.sourceforge.net/,可以去上面下载最新JAR包,

本项目用的是cglib-3.0.jar

本项目还加入了依赖JAR包asm-4.0.jar,asm-util-4.0.jar

实现方式如下

Eg:

测试代理类方法



1, CGLIB实现方式是对代理的目标类进行继承

2, 生成出了的代理类可以没方法,生成出来的类可以直接转换成目标类或目标类实现接口的实现类,因JAVA向上转换

明显特点:通过输出看出,看出生成出的代理类的parent类为代理的目标类



Spring  AOP的代理类机制分析


在spring中,bean都是由动态代理生成出来的,那么到底是用JDK的Proxy类实现呢,还是用CGLIB方式实现呢。

AOP  Spring需要的依赖JAR包有:

spring-asm-3.2.0.M1.jar

spring-beans-3.2.0.M1.jar

spring-context-3.2.0.M1.jar

spring-core-3.2.0.M1.jar

spring-expression-3.2.0.M1.jar

spring-aop-3.2.0.M1.jar

spring-aspects-3.2.0.M1.jar

commons\commons-logging-1.1.1\commons-logging-1.1.1.jar

aopalliance\aopalliance.jar

lib\aspectjweaver.jar



实现AOP

先简单的实现AOP
配置如下

然后进行运行结果如下,表示AOP拦截成功

TestAspect.java


AOP测试类

输出:

do something in befor

welcome for test,My QQ is 332003231

do something in after

打印代理类的生成方式


第一种情况, Test不实现任何接口,代码如下


在TestBeans中加入打印当前对象的名称

如下:

输出:

Test$$EnhancerByCGLIB$$4791b36c

super class is class org.ben.spring.service.Test

do something in befor

welcome for test,My QQ is 332003231

do something in after



明显看到用了AOP之后,输出的是代理类对象Test$$EnhancerByCGLIB$$bb9b6a7c.而且它的父类是我们的代理目标类。说明是有CGLIB生成的


第二种情况

XML的配置不变,改变代理目标类Test的实现方法,如下

和原来不同的是多继承了一个接口,接口中定义了say()方法

在TestBeans中加入打印当前对象的名称

如下:



输出:

$Proxy0

super class is class java.lang.reflect.Proxy

do something in befor

welcome for test,My QQ is 332003231

do something in after

结论
Spring AOP中,当拦截对象实现了接口时,生成方式是用JDK的Proxy类。当没有实现任何接口时用的是GCLIB开源项目生成的拦截类的子类.

附上本文测试的源码内容

来源:Heck's Blog
地址:http://www.hecks.tk/post/422/
转载时须以链接形式注明作者和原始出处及本声明,否则将追究法律责任,谢谢配合!