beanPostProcessor
2015-11-26 21:28
633 查看
最近想对项目中的所有bean进行一个代理。然后监控bean得方法的使用情况。
刚开始想的方法是:重写项目的beanFactory,然后再getBean的使用,对结果object进行一个代理,达到我的目的。但是发现重写getBean的方法,无法对bean中的依赖注入的bean(set进来的bean)进行代理。
正好看到了beanPostProcessor的使用方法。可以在spring的xml的配置一个BeanPostProcessor,然后对所有的bean进行一个代理处理,正好可以满足我的需求!
BeanPostProcessor代码如下:
Java代码
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代码如下:
Java代码
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);
}
}
感觉还是比较好使的!记录一下。以后再有监控的需求,可以考虑使用这种方式了!
刚开始想的方法是:重写项目的beanFactory,然后再getBean的使用,对结果object进行一个代理,达到我的目的。但是发现重写getBean的方法,无法对bean中的依赖注入的bean(set进来的bean)进行代理。
正好看到了beanPostProcessor的使用方法。可以在spring的xml的配置一个BeanPostProcessor,然后对所有的bean进行一个代理处理,正好可以满足我的需求!
BeanPostProcessor代码如下:
Java代码
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代码如下:
Java代码
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);
}
}
感觉还是比较好使的!记录一下。以后再有监控的需求,可以考虑使用这种方式了!
相关文章推荐
- php正则表达式速查手册
- 兔子-提高xampp中php的版本/提高php项目的版本
- 安装PHP运行环境时候vcruntime140.dll问题的解决方法
- php获取当前毫秒时间戳
- PHP中正则表达式的用法
- thinkphp+datatables+ajax 大量数据服务器端查询
- neo4j-neoclient-example之movies 推荐
- 关于thinkphp中的验证码生成与刷新
- PHP出现Cannot modify header information问题的解决方法
- 【php wamp的配置】
- php Socket通信
- laravel whereRaw 和 where(DB::raw(''))
- 解析提高PHP执行效率的50个技巧
- 究极!ThinkPHP 3.2.2 框架源码逐行分析(一)
- PHP实现从1累加到100(1+2+….+100=)的几种思路
- 用PHP实现一个Amazon SES的代理服务器
- 完美解决php验证码session不同步的问题
- PHP 9 大缓存技术总结
- PHP从某个关联数组中取出某一列KEY的值并放入另一个数组中
- 兔子-查看当前php的版本