最近想对项目中的所有bean进行一个代理。然后监控bean得方法的使用情况。
刚开始想的方法是:重写项目的beanFactory,然后再getBean的使用,对结果object进行一个代理,达到我的目的。但是发现重写getBean的方法,无法对bean中的依赖注入的bean(set进来的bean)进行代理。
正好看到了beanPostProcessor的使用方法。可以在spring的xml的配置一个BeanPostProcessor,然后对所有的bean进行一个代理处理,正好可以满足我的需求!
BeanPostProcessor代码如下:
import java.lang.reflect.Proxy; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import com.alibaba.common.logging.Logger; import com.alibaba.common.logging.LoggerFactory; public class MyBeanPostProcesser implements BeanPostProcessor { private Map map = new ConcurrentHashMap(100); private static final Logger log = LoggerFactory.getLogger("myBeanPostProcesser"); public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { MyProxy proxy = new MyProxy(); if (beanName.contains("DB")) { return bean; } if (bean.toString().contains("Proxy")) { log.info(beanName + "为代理类,不进行再次代理!"); return bean; } if (beanName.contains("TransactionTemplate")) { log.info(beanName + "为TransactionTemplate类,不进行再次代理!该类为:" + bean); return bean; } if (map.get(beanName) != null) { log.info(beanName + "已经代理过,不进行再次代理!"); return map.get(beanName); } proxy.setObj(bean); proxy.setName(beanName); Class[] iterClass = bean.getClass().getInterfaces(); if (iterClass.length > 0) { Object proxyO = Proxy.newProxyInstance(bean.getClass().getClassLoader(), iterClass, proxy); map.put(beanName, proxyO); return proxyO; } else { log.info(beanName + "么有接口不进行代理!"); return bean; } } public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } }
代理类Proxy代码如下:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import com.alibaba.common.logging.Logger; import com.alibaba.common.logging.LoggerFactory; import sun.reflect.Reflection; public class MyProxy implements InvocationHandler { private static final Logger log = LoggerFactory.getLogger("myself"); private Object obj; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Object getObj() { return obj; } public void setObj(Object obj) { this.obj = obj; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("begin================" + "bean 名称为【" + name + "】方法为【" + method.getName() + "】=========" + obj.getClass()); log.error("begin================" + "bean 名称为【" + name + "】方法为【" + method.getName() + "】=========" + obj.getClass()); return method.invoke(obj, args); } public void printDetail(String detail) { log.error(detail); } }
感觉还是比较好使的!记录一下。以后再有监控的需求,可以考虑使用这种方式了!