林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka
动态代理:在程序运行时,运用反射机制动态创建而成。
我们知道,通过使用代理,可以在被代理的类的方法的前后添加一些处理方法,这样就达到了类似AOP的效果。而JDK中提供的动态代理,就是实现AOP的绝好底层技术。
还有一个叫CGLib的动态代理,CGLib全称为Code Generation Library,是一个强大的高性能,高质量的代码生成类库,可以在运行期扩展Java类与实现Java接口,CGLib封装了asm,可以再运行期动态生成新的class。和JDK动态代理相比较:JDK创建代理有一个限制,就是只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,则可以通过CGLib创建动态代理
(以下代码来自Spring.3.x企业应用开发实战,其中有些地方笔者做了些增加)
1、接口ForumService
package aop;
public interface ForumService {
public void removeTopic(int topic);
public void removeForum(int forumId);
}
2、ForumServiceImpl实现package aop;
public class ForumServiceImpl implements ForumService{
public void removeTopic(int topic){
System.out.println("模拟删除记录"+topic);
try{
Thread.currentThread().sleep(20);
}catch(Exception e){
throw new RuntimeException(e);
}
}
public void removeForum(int forumId){
System.out.println("模拟删除记录"+forumId);
try{
Thread.currentThread().sleep(20);
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
这里我们可以来看看上面的方法:先测试下:
ForumServiceImpl forumServiceImpl=new ForumServiceImpl(); forumServiceImpl.removeForum(190); forumServiceImpl.removeTopic(123);
接下来我们要实现在删除记录之前和之后增加一些方法
3、要在ForumServiceImpl.java中插入的增强方法
package aop;
public class PerformanceMonitor {
private static ThreadLocal<MethodPerformance> performanceRecord=new ThreadLocal<MethodPerformance>();
public static void begin(String method){
System.out.println("begin monitor..");
MethodPerformance mp=new MethodPerformance(method);
performanceRecord.set(mp);
}
public static void end(){
System.out.println("end monitor...");
MethodPerformance mp=performanceRecord.get();
mp.printPerformance();
}
}
MethodPerformance.java是真正加入的方法
package aop;
public class MethodPerformance {
private long begin;
private long end;
private String serviceMethod;
public MethodPerformance(String serviceMethod){
this.serviceMethod=serviceMethod;
this.begin=System.currentTimeMillis();
}
public void printPerformance(){
end=System.currentTimeMillis();
long elapse=end-begin;
System.out.println(serviceMethod+"花费"+elapse+"毫秒");
}
} package aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class PerformanceHandler implements InvocationHandler {
private Object target;
public PerformanceHandler(Object object) {
this.target = object;
}
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
PerformanceMonitor.begin(target.getClass().getName() + "."
+ arg1.getName());
Object obj = arg1.invoke(target, arg2);
PerformanceMonitor.end();
return obj;
}
}
ForumServiceImpl target=new ForumServiceImpl();
PerformanceHandler handler=new PerformanceHandler(target);
ForumService proxy=(ForumService)Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), handler);
proxy.removeForum(23);
proxy.removeTopic(678);
System.out.println("end monitor...");结果:
1、CglibProxy.java
package aop;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class CglibProxy implements MethodInterceptor{
private Enhancer enhancer=new Enhancer();
public Object getProxy(Class clazz){
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
PerformanceMonitor.begin(arg0.getClass().getName() + "."
+ arg1.getName());
Object obj = arg3.invoke(arg0, arg2);
PerformanceMonitor.end();
return obj;
}
}
2、测试 CglibProxy proxy2=new CglibProxy();
ForumServiceImpl forumServiceImpl=(ForumServiceImpl)proxy2.getProxy(ForumServiceImpl.class);
forumServiceImpl.removeForum(456);
forumServiceImpl.removeTopic(987);
System.out.println("end monitor...");3、结果:CGLib所创建的动态代理对象的性能比JDK所创建的代理对象性能高不少,大概10倍,但CGLib在创建代理对象时所花费的时间却比JDK动态代理多大概8倍,所以对于singleton的代理对象或者具有实例池的代理,因为无需频繁的创建新的实例,所以比较适合CGLib动态代理技术,反之则适用于JDK动态代理技术。另外,由于CGLib采用动态创建子类的方式生成代理对象,所以不能对目标类中的final,private等方法进行处理。所以,大家需要根据实际的情况选择使用什么样的代理了。同样的,Spring的AOP编程中相关的ProxyFactory代理工厂内部就是使用JDK动态代理或CGLib动态代理的,通过动态代理,将增强(advice)应用到目标类中。
林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka
原文地址:http://blog.csdn.net/evankaka/article/details/45195383