/* ==================================================================
* Created [2009-4-27 下午11:32:55] by Jon.King
* ==================================================================
* TSS
* ==================================================================
* mailTo:jinpujun@hotmail.com
* Copyright (c) Jon.King, 2009-2012
* ==================================================================
*/
package com.jinhe.tss.core.cachepool.proxy.profier;
import java.lang.reflect.Method;
import java.util.Arrays;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.NoOp;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
/**
* <p>
* Profiler.java
* </p>
* <p>性能测量CGLIB实现,适合所有对象,尤其是没有实现接口的对象。
* </p><p>(注,使用本类的前提是:对象的初始化需由CGLIB完成)
* </p><p>计算对象方法的执行时间。
* </p><p>可指定拦截对象需要被拦截测试的具体方法列。
* </p>
*
* 与Dynamic Proxy中的Proxy和InvocationHandler相对应,net.sf.cglib.proxy.Enhancer和MethodInterceptor
* 在CGLib中负责完成(代理对象创建)和(方法截获处理), (产生的是目标类的子类)而不是通过接口来实现方法拦截的,
* Enhancer主要是用于构造动态代理子类来实现拦截,
* MethodInterceptor(扩展了Callback接口)主要用于实现around advice(AOP中的概念):
*
* @author Jon.King 2007-1-9
*/
public class CGLIBProfiler implements MethodInterceptor {
private Logger log = Logger.getLogger(CGLIBProfiler.class);
/**
* 默认拦截所有的方法。
* @param clazz 指定拦截对象
* @return
*/
public Object getProxy(Class<?> clazz) {
return getProxy(clazz, null);
}
/**
* 指定拦截对象,同时指定拦截对象需要被拦截测试的具体方法列。
* @param clazz 指定拦截对象
* @param invokeMethods 指定拦截对象需要被拦截测试的具体方法列
* @return
*/
public Object getProxy(Class<?> clazz, String[] invokeMethods) {
Callback[] callbacks = new Callback[] { this, NoOp.INSTANCE };
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallbacks(callbacks);
enhancer.setCallbackFilter(this.new CallbackFilterImpl(invokeMethods));
return enhancer.create();
}
/**
* 如果构造函数带参数,则调用本方法实现
* @param clazz
* @param paramTypes
* @param params
* @param invokeMethods
* @return
*/
public Object getProxy(Class<?> clazz, Class<?>[] paramTypes, Object[] params, String[] invokeMethods) {
Callback[] callbacks = new Callback[] { this, NoOp.INSTANCE };
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallbacks(callbacks);
enhancer.setCallbackFilter(this.new CallbackFilterImpl(invokeMethods));
return enhancer.create(paramTypes, params);
}
public Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable {
log.setLevel(Level.INFO);
long startTime = System.currentTimeMillis();
Object result = proxy.invokeSuper(o, args);
long endTime = System.currentTimeMillis();
log.info("方法【" + method.getName() + "(" + Arrays.asList(args).toString() + ")】执行时间为" + (endTime - startTime) + "(ms).");
return result;
}
private class CallbackFilterImpl implements CallbackFilter {
private String[] invokeMethods;
private String[] ignoreMethods = new String[] {"print", "set", "getWriter", "doAfterSave"};
public CallbackFilterImpl(String[] invokeMethods){
this.invokeMethods = invokeMethods;
}
public CallbackFilterImpl(String[] invokeMethods, String[] ignoreMethods){
this.invokeMethods = invokeMethods;
this.ignoreMethods = ignoreMethods;
}
/*
* 定义过滤或者拦截哪些方法,0:拦截 1:不拦截
*/
public int accept(Method method) {
String methodName = method.getName();
if(ignoreMethods != null && ignoreMethods.length > 0) {
for(String temp : ignoreMethods) {
if(methodName.startsWith(temp)) {
return 1;
}
}
return 0;
}
if(invokeMethods == null || invokeMethods.length == 0) return 0;
if(Arrays.asList(invokeMethods).contains(methodName)) return 0;
return 1;
}
}
}