首页 > 代码库 > BeanPostProcessor使用心得

BeanPostProcessor使用心得

最近想对项目中的所有bean进行一个代理。然后监控bean得方法的使用情况。


        刚开始想的方法是:重写项目的beanFactory,然后再getBean的使用,对结果object进行一个代理,达到我的目的。但是发现重写getBean的方法,无法对bean中的依赖注入的bean(set进来的bean)进行代理。
 
       正好看到了beanPostProcessor的使用方法。可以在spring的xml的配置一个BeanPostProcessor,然后对所有的bean进行一个代理处理,正好可以满足我的需求!
 
BeanPostProcessor代码如下:
Java代码  技术分享
  1. import java.lang.reflect.Proxy;  
  2. import java.util.Map;  
  3. import java.util.concurrent.ConcurrentHashMap;  
  4.   
  5. import org.springframework.beans.BeansException;  
  6. import org.springframework.beans.factory.config.BeanPostProcessor;  
  7.   
  8. import com.alibaba.common.logging.Logger;  
  9. import com.alibaba.common.logging.LoggerFactory;  
  10.   
  11. public class MyBeanPostProcesser implements BeanPostProcessor {  
  12.     private Map map = new ConcurrentHashMap(100);  
  13.     private static final Logger log = LoggerFactory.getLogger("myBeanPostProcesser");  
  14.   
  15.     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  
  16.         MyProxy proxy = new MyProxy();  
  17.   
  18.         if (beanName.contains("DB")) {  
  19.             return bean;  
  20.         }  
  21.   
  22.         if (bean.toString().contains("Proxy")) {  
  23.             log.info(beanName + "为代理类,不进行再次代理!");  
  24.             return bean;  
  25.         }  
  26.         if (beanName.contains("TransactionTemplate")) {  
  27.             log.info(beanName + "为TransactionTemplate类,不进行再次代理!该类为:" + bean);  
  28.             return bean;  
  29.         }  
  30.   
  31.         if (map.get(beanName) != null) {  
  32.             log.info(beanName + "已经代理过,不进行再次代理!");  
  33.             return map.get(beanName);  
  34.         }  
  35.         proxy.setObj(bean);  
  36.         proxy.setName(beanName);  
  37.         Class[] iterClass = bean.getClass().getInterfaces();  
  38.         if (iterClass.length > 0) {  
  39.             Object proxyO = Proxy.newProxyInstance(bean.getClass().getClassLoader(), iterClass, proxy);  
  40.             map.put(beanName, proxyO);  
  41.             return proxyO;  
  42.         } else {  
  43.             log.info(beanName + "么有接口不进行代理!");  
  44.             return bean;  
  45.         }  
  46.     }  
  47.   
  48.     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {  
  49.         return bean;  
  50.     }  
  51.   
  52. }  
 
 
代理类Proxy代码如下:
Java代码  技术分享
  1. import java.lang.reflect.InvocationHandler;  
  2. import java.lang.reflect.Method;  
  3.   
  4. import com.alibaba.common.logging.Logger;  
  5. import com.alibaba.common.logging.LoggerFactory;  
  6.   
  7. import sun.reflect.Reflection;  
  8.   
  9. public class MyProxy implements InvocationHandler {  
  10.     private static final Logger log = LoggerFactory.getLogger("myself");  
  11.   
  12.     private Object obj;  
  13.   
  14.     private String name;  
  15.   
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.   
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.   
  24.     public Object getObj() {  
  25.         return obj;  
  26.     }  
  27.   
  28.     public void setObj(Object obj) {  
  29.         this.obj = obj;  
  30.     }  
  31.   
  32.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  33.         System.out.println("begin================" + "bean 名称为【" + name + "】方法为【" + method.getName() + "】========="  
  34.                 + obj.getClass());  
  35.         log.error("begin================" + "bean 名称为【" + name + "】方法为【" + method.getName() + "】========="  
  36.                 + obj.getClass());  
  37.         return method.invoke(obj, args);  
  38.     }  
  39.   
  40.     public void printDetail(String detail) {  
  41.         log.error(detail);  
  42.     }  
  43.   
  44. }  
 
感觉还是比较好使的!记录一下。以后再有监控的需求,可以考虑使用这种方式了!

BeanPostProcessor使用心得