/* ================================================================== * 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; } } }