cglib代理,出现cannot be cast to java.lang.Number

测试类

public class SampleClass {
    public String test(String input){
        return "hello world";
    }
}

用cglib对代码进行增强

public static void main(String[] args) {
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(SampleClass.class);
    enhancer.setCallback(new FixedValue() {
        @Override
        public Object loadObject() throws Exception {
            return "Hello cglib";
        }
    });
    SampleClass proxy = (SampleClass) enhancer.create();
    System.out.println(proxy.test(null)); //拦截test,输出Hello cglib
    System.out.println(proxy.toString()); 
    System.out.println(proxy.getClass());
    System.out.println(proxy.hashCode());
}

测试结果输出

Hello cglib
Hello cglib
class com.zeus.cglib.SampleClass$$EnhancerByCGLIB$$e3ea9b7

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

    at com.zeus.cglib.SampleClass$$EnhancerByCGLIB$$e3ea9b7.hashCode(<generated>)
    ...

上述代码中,FixedValue用来对所有拦截的方法返回相同的值,从输出我们可以看出来,Enhancer对非final方法test()、toString()、hashCode()进行了拦截,没有对getClass进行拦截。由于hashCode()方法需要返回一个Number,但是我们返回的是一个String,这解释了上面的程序中为什么会抛出异常。

### Cglib代理导致的`InaccessibleObjectException`问题分析 当使用Cglib代理时,可能会遇到`InaccessibleObjectException`异常。此问题通常发生在尝试访问某些受保护或受限的方法/字段时,尤其是在JDK 9及以上版本中引入模块化系统(即JPMS, Java Platform Module System)之后[^1]。 #### 原因解析 自JDK 9起,Java引入了模块化的概念,增强了类加载器的安全性和封装性。默认情况下,许多内部API被限制访问,除非显式声明开放权限。如果Cglib试图通过反射修改这些不可见成员(如protected final方法),就会抛出`InaccessibleObjectException`异常。 #### 解决方案 以下是几种可能的解决方案: 1. **启用强名访问控制** 可以通过启动参数设置来放宽对特定包的访问限制。例如,在运行程序时添加如下选项: ```bash --add-opens java.base/java.lang=ALL-UNNAMED ``` 这一命令会打开`java.base`模块中的`java.lang`包给未命名模块使用,从而允许Cglib对其进行操作。 2. **升级依赖库** 确保使用的Spring框架或其他涉及AOP功能的相关组件已更新至最新稳定版。新版本往往针对不同JDK环境进行了兼容性优化处理。 3. **调整代码逻辑** 如果条件允许,可以考虑重构业务逻辑,减少对于那些难以直接操控部分的需求;或者切换到其他不依赖深层反射机制的技术实现方式,比如纯接口型动态代理模式等替代方案。 4. **定制ClassLoader** 创建自定义类加载器实例并重写其中findClass()方法来自行管理资源定位过程,则有可能绕过标准安全策略检查流程达到目的。不过这种方法风险较高且维护成本较大,需谨慎评估利弊后再决定是否采用。 ```python import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; public class CustomEnhancer implements MethodInterceptor { public static void main(String[] args){ Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(TargetClass.class); enhancer.setCallback(new CustomEnhancer()); TargetClass proxy=(TargetClass)enhancer.create(); } @Override public Object intercept(Object obj, java.lang.reflect.Method method, Object[] arguments,net.sf.cglib.proxy.MethodProxy proxyMethod) throws Throwable{ return null; // Implement your logic here. } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值