CGLIB无法拦截静态方法
我在用cglib实现动态代理功能时,发现无法拦截静态方法,而是直接调用的静态方法。
追踪了一下源码,发现把静态方法过滤掉了,没做拦截。
代理模式中的真实角色和代理角色都继承或实现一个抽象类或接口,甚至普通的类也行,都是代理模式的大致意思,代理角色中传入真实角色实例后,在调用真实方法前后或做处理。
那么,既然抽象出来的那“哥们”,可以是类,比如cglib中就是利用继承,对pojo进行动态字节码生成其子类,即生成的代理角色,但是不代理static普通方法,而我自己写一个靠继承实现的代理的话,显然能实现,即重写抽象出的类的static普通方法。
想问问,为什么会这样,为什么要这样?恳请各位解答,不甚感激!
下面是做的例子,比较了static和非static方法被拦截的情况。
真实对象
public class TargetObject {
public static void businessLogic() {
System.out.println("目标对象/真实对象中的 业务逻辑处理");
}
}
具体代理控制逻辑,实现MethodInterceptor接口
public class AroundAdvice implements MethodInterceptor {
/*
* 重写方法
*
* @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object,
* java.lang.reflect.Method, java.lang.Object[],
* net.sf.cglib.proxy.MethodProxy)
*/
/**
* Parameters: obj - "this", the enhanced object
*
* method - intercepted Method args - argument array; primitive types are
* wrapped
*
* proxy - used to invoke super (non-intercepted method); may be called as
* many times as needed
*
* Returns: any value compatible with the signature of the proxied method.
* Method returning void will ignore this value.
*/
@Override
public Object intercept(Object target, Method method, Object[] arg2,
MethodProxy methodProxy) throws Throwable {
System.out.println("目标对象/真实对象 方法调用之前...");
Object result=methodProxy.invokeSuper(target,arg2);
System.out.println("目标对象/真实对象 方法调用之后...");
return result+"<--真实对象的返回值。 \"通知\"中的新加内容";
}
}
生成代理对象的工具类
public class ProxyUtil {
public static TargetObject getProxy() {
// 增强处理器:拦截的方法插入代理控制逻辑的处理器
Enhancer enhancer = new Enhancer();
// 设置要代理的目标类
enhancer.setSuperclass(TargetObject.class);
// 设置要代理的拦截器
enhancer.setCallback(new AroundAdvice());
// 生成并返回代理对象
return (TargetObject) enhancer.create();
}
}
测试类
public class Test {
public static void main(String[] args) {
TargetObject targetObject = ProxyUtil.getProxy();
targetObject.businessLogic();
}
}
TargetObject中的方法为static修饰时,打印:
目标对象/真实对象中的 业务逻辑处理
去掉static,打印:
目标对象/真实对象 方法调用之前...
目标对象/真实对象中的 业务逻辑处理
目标对象/真实对象 方法调用之后...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
静态代理用AspectJ,我特地用AspectJ试了下,单纯的AspectJ也实现不了。不过用asm可以实现,运行期间修改class字节码实现的,不过很麻烦啊,你要是没什么特殊需求还是规规矩矩的正常写吧。稍后我放一段asm怎么改的
不管怎样,下面我还是贴一下asm的实现
为什么cglib不能拦截静态方法是因为Cglib的实现方式:生成的代理类继承自被代理类/目标类,请求时,执行自己织入的增强,然后再执行目标方法,因而使用继承方式创建代理类不能代理任何final方法和类,以及静态方法。