com.alibaba.druid.support.spring.stat.DruidStatInterceptor Maven / Gradle / Ivy
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.support.spring.stat;
import com.alibaba.druid.filter.stat.StatFilterContext;
import com.alibaba.druid.filter.stat.StatFilterContextListenerAdapter;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.TargetSource;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import java.lang.reflect.Method;
public class DruidStatInterceptor implements MethodInterceptor, InitializingBean, DisposableBean {
public static final String PROP_NAME_PROFILE = "druid.profile";
private static final Log LOG = LogFactory.getLog(DruidStatInterceptor.class);
private static SpringStat springStat = new SpringStat();
private SpringMethodContextListener statContextListener = new SpringMethodContextListener();
public DruidStatInterceptor() {
}
@Override
public void afterPropertiesSet() throws Exception {
SpringStatManager.getInstance().addSpringStat(springStat);
StatFilterContext.getInstance().addContextListener(statContextListener);
}
@Override
public void destroy() throws Exception {
StatFilterContext.getInstance().removeContextListener(statContextListener);
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
SpringMethodStat lastMethodStat = SpringMethodStat.current();
SpringMethodInfo methodInfo = getMethodInfo(invocation);
SpringMethodStat methodStat = springStat.getMethodStat(methodInfo, true);
if (methodStat != null) {
methodStat.beforeInvoke();
}
long startNanos = System.nanoTime();
Throwable error = null;
try {
return invocation.proceed();
} catch (Throwable e) {
error = e;
throw e;
} finally {
long endNanos = System.nanoTime();
long nanos = endNanos - startNanos;
if (methodStat != null) {
methodStat.afterInvoke(error, nanos);
}
SpringMethodStat.setCurrent(lastMethodStat);
}
}
public SpringMethodInfo getMethodInfo(MethodInvocation invocation) {
Object thisObject = invocation.getThis();
Method method = invocation.getMethod();
if (thisObject == null) {
return new SpringMethodInfo(method.getDeclaringClass(), method);
}
if (method.getDeclaringClass() == thisObject.getClass()) {
return new SpringMethodInfo(method.getDeclaringClass(), method);
}
{
Class> clazz = thisObject.getClass();
boolean isCglibProxy = false;
boolean isJavassistProxy = false;
for (Class> item : clazz.getInterfaces()) {
if (item.getName().equals("net.sf.cglib.proxy.Factory")) {
isCglibProxy = true;
break;
} else if (item.getName().equals("javassist.util.proxy.ProxyObject")) {
isJavassistProxy = true;
break;
}
}
if (isCglibProxy || isJavassistProxy) {
Class> superClazz = clazz.getSuperclass();
return new SpringMethodInfo(superClazz, method);
}
}
Class> clazz = null;
try {
// 最多支持10层代理
for (int i = 0; i < 10; ++i) {
if (thisObject instanceof org.springframework.aop.framework.Advised) {
TargetSource targetSource = ((org.springframework.aop.framework.Advised) thisObject).getTargetSource();
if (targetSource == null) {
break;
}
Object target = targetSource.getTarget();
if (target != null) {
thisObject = target;
} else {
clazz = targetSource.getTargetClass();
break;
}
} else {
break;
}
}
} catch (Exception ex) {
LOG.error("getMethodInfo error", ex);
}
if (clazz == null) {
return new SpringMethodInfo(method.getDeclaringClass(), method);
}
return new SpringMethodInfo(clazz, method);
}
class SpringMethodContextListener extends StatFilterContextListenerAdapter {
@Override
public void addUpdateCount(int updateCount) {
SpringMethodStat springMethodStat = SpringMethodStat.current();
if (springMethodStat != null) {
springMethodStat.addJdbcUpdateCount(updateCount);
}
}
@Override
public void addFetchRowCount(int fetchRowCount) {
SpringMethodStat springMethodStat = SpringMethodStat.current();
if (springMethodStat != null) {
springMethodStat.addJdbcFetchRowCount(fetchRowCount);
}
}
@Override
public void executeBefore(String sql, boolean inTransaction) {
SpringMethodStat springMethodStat = SpringMethodStat.current();
if (springMethodStat != null) {
springMethodStat.incrementJdbcExecuteCount();
}
}
@Override
public void executeAfter(String sql, long nanos, Throwable error) {
SpringMethodStat springMethodStat = SpringMethodStat.current();
if (springMethodStat != null) {
springMethodStat.addJdbcExecuteTimeNano(nanos);
if (error != null) {
springMethodStat.incrementJdbcExecuteErrorCount();
}
}
}
@Override
public void commit() {
SpringMethodStat springMethodStat = SpringMethodStat.current();
if (springMethodStat != null) {
springMethodStat.incrementJdbcCommitCount();
}
}
@Override
public void rollback() {
SpringMethodStat springMethodStat = SpringMethodStat.current();
if (springMethodStat != null) {
springMethodStat.incrementJdbcRollbackCount();
}
}
@Override
public void pool_connect() {
SpringMethodStat springMethodStat = SpringMethodStat.current();
if (springMethodStat != null) {
springMethodStat.incrementJdbcPoolConnectionOpenCount();
}
}
@Override
public void pool_close(long nanos) {
SpringMethodStat springMethodStat = SpringMethodStat.current();
if (springMethodStat != null) {
springMethodStat.incrementJdbcPoolConnectionCloseCount();
}
}
@Override
public void resultSet_open() {
SpringMethodStat springMethodStat = SpringMethodStat.current();
if (springMethodStat != null) {
springMethodStat.incrementJdbcResultSetOpenCount();
}
}
@Override
public void resultSet_close(long nanos) {
SpringMethodStat springMethodStat = SpringMethodStat.current();
if (springMethodStat != null) {
springMethodStat.incrementJdbcResultSetCloseCount();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy