All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.unidal.spring.TrackableBeanPostProcessor Maven / Gradle / Ivy

The newest version!
package org.unidal.spring;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.stereotype.Service;

import com.dianping.cat.Cat;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;

public class TrackableBeanPostProcessor implements BeanPostProcessor {
   private BeanNaming m_naming = new DefaultBeanNaming();

   private boolean m_useCglib = false;

   @Override
   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      Class beanClass = bean.getClass();

      if (beanClass.isAnnotationPresent(Trackable.class)) {
         TrackableInvocationHandler handler = new TrackableInvocationHandler(m_naming, bean);

         if (m_useCglib) {
            return Enhancer.create(bean.getClass(), handler);
         } else {
            return Proxy.newProxyInstance(beanClass.getClassLoader(), beanClass.getInterfaces(), handler);
         }
      }

      return bean;
   }

   @Override
   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }

   protected static interface BeanNaming {
      public String getData(Object instance, Method method, Object[] args);

      public String getName(Object instance, Method method, Object[] args);

      public String getType(Object instance, Method method, Object[] args);
   }

   protected static class DefaultBeanNaming implements BeanNaming {
      @Override
      public String getData(Object instance, Method method, Object[] args) {
         return Arrays.asList(args).toString();
      }

      @Override
      public String getName(Object instance, Method method, Object[] args) {
         Class[] types = method.getParameterTypes();
         StringBuilder sb = new StringBuilder(256);
         boolean first = true;

         sb.append(method.getName());
         sb.append('(');

         for (Class type : types) {
            if (first) {
               first = false;
            } else {
               sb.append(',');
            }

            sb.append(type.getSimpleName());
         }

         sb.append(')');

         return sb.toString();
      }

      @Override
      public String getType(Object instance, Method method, Object[] args) {
         Service service = instance.getClass().getAnnotation(Service.class);

         if (service != null) {
            String value = service.value();

            if (value.length() > 0) {
               return value;
            }
         }

         return instance.getClass().getName();
      }
   }

   protected static class TrackableInvocationHandler implements InvocationHandler, MethodInterceptor {
      private BeanNaming m_naming;

      private Object m_bean;

      public TrackableInvocationHandler(BeanNaming naming, Object bean) {
         m_naming = naming;
         m_bean = bean;
      }

      @Override
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         return intercept(m_bean, method, args, null);
      }

      @Override
      public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
         String type = m_naming.getType(m_bean, method, args);
         String name = m_naming.getName(m_bean, method, args);
         String data = m_naming.getData(m_bean, method, args);
         Transaction t = Cat.newTransaction(type, name);

         if (data != null) {
            t.addData(data);
         }

         try {
            if (!method.isAccessible()) {
               method.setAccessible(true);
            }

            Object value = method.invoke(m_bean, args);

            t.setStatus(Message.SUCCESS);
            return value;
         } catch (Throwable e) {
            t.setStatus(e);
            Cat.logError(e);
            throw e;
         } finally {
            t.complete();
         }
      }
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy