- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我使用 cglib MethodInterceptor
来包装服务。在对服务的每次调用中,它应该打开数据 session ,将调用传递给服务并最终关闭 session 。
但是,我注意到它在从 Finalizer
调用时行为不正常。我得到以下堆栈跟踪:
java.lang.IllegalArgumentException: interface my.pkg.SomeInterface is not visible from class loader
at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581)
at my.pkg.ProxyFactory.create(ProxyFactory.java:68)
at my.pkg.SomeService.make(SomeService.java:181)
at my.pkg.SomeService$SessionWrappingInterceptor.intercept(SomeService.java:1275)
at my.pkg.SomeService$$EnhancerByCGLIB$$b58faf6a.finalize(<generated>)
at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)
at java.lang.ref.Finalizer.access$100(Finalizer.java:14)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)
我做错了什么?我该如何解决?
最佳答案
当终结器最终选择您的对象(或您的 CGLIB 代理对象)进行终结时,垃圾收集器已确定您的对象无法访问并且即将被丢弃/收集。让我们假设这不是唯一被收集的对象,事实上它过去可能使用过的其他对象(包括它们的类加载器)也已被收集。
你的问题中没有足够的信息来确定发生了什么,但我的一般猜测是你的 ProxyFactory 正在做的工作需要这个类加载器曾经可以访问但不再可以访问的类,可能是由于事实上,您正处于垃圾收集的最后阶段。
我已经了解到处理 finalize() 调用的代理是非常危险的。在大多数情况下,您的代理目标确实不需要处理该调用,但如果需要,请不要在您的代理处理程序中执行任何创建、初始化或以其他方式创建对代理目标的引用的操作。 (例如,我的案例是一个按需加载的对象。当调用 finalize() 时,如果之前没有加载该对象,它将加载它并将值缓存在创建新的强引用链的某个地方,从而不允许代理类、它的类加载器和它引用的许多其他类被收集。大量内存泄漏。)
我的建议(虽然晚了)是禁止您的代理处理 finalize()。可以为 CGLIB 的增强器提供 CallbackFilters 以指示不要对 finalize() 方法执行任何操作,或者如果您使用的是简单的 MethodInterceptor,您可以自己检查一下。
最后一条评论:小心 CallbackFilter秒。它们也可能导致内存泄漏,尤其是当它们来自与 CGLIB 不同的类加载器时!您最终会得到 CGLIB 生成的对象,这些对象保留在不会被垃圾收集的 CallbackFilter 实例上。
关于java - cglib - MethodInterceptor & 完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6517348/
Spring不包含cglib依赖,cglib和spring cglib都有Enhancer类,一个是net.sf.cglib.proxy.Enhancer,另一个是org.springframewor
我正在尝试构建一个大型项目,但由于以下错误而失败: [INFO] -------------------------------------------------------------------
关闭。这个问题不符合 Stack Overflow guidelines 。它目前不接受答案。 想改善这个问题吗?更新问题,以便堆栈溢出为 on-topic。 7年前关闭。 Improve this
@Service public class TestService{ @DynamicReference private ITestProvider testProvider;
我有以下通用 cglib 方法拦截器实现: public class EntityInterceptor implements MethodInterceptor{ private Entit
假设我有一些 A 类,它具有 B 类的属性。 public class ClassA{ private ClassB classB; public ClassA(ClassB classB){ th
我正在使用 CGLib 来增强 A 类。 public class A { public void printName(){ System.out.println("guy");
我的 Controller 在其属性上使用了 @Value 注释,但是发生了一些奇怪的事情: 08:20:31.400 [main] ERROR Controller - postConstruct(
我想做的是序列化一个类实现一个命令模式,以便我稍后可以运行它。在最好的在所有世界中,我想序列化一个匿名类(我是意识到这个问题) 让事情变得有点复杂的是我在 Spring 的环境中并且我希望序列化的匿名
谁能给我一个 Java CGLib 的好例子 Mixin类用法?我一直在挖掘它们似乎都不够简单。 最佳答案 很简单: import static org.junit.Assert.*; import
在实际项目中,考虑到不同的数据使用者,我们经常要处理 VO、DTO、Entity、DO 等对象的转换,如果手动编写 setter/getter 方法一个个赋值,将非常繁琐且难维护。通常情况下,这类转换
代码如下: Patient patient = factory.createPatient(); Enhancer enhancer = new Enhancer(
我有两个类 @Component @Scope(proxyMode=ScopedProxyMode.TARGET_CLASS,value="session") public clas
代码是用 Scala 编写的,但希望 Java 程序员也能理解。 我有以下类(class): class SampleClass { def test(in: String) = "Hello w
我无法为 HttpURLConnection 类创建动态代理,因为它没有公共(public)构造函数来创建增强器。根据要求,我想创建一个动态代理以在运行时获取当前连接的详细信息。 我尝试使用this教
我想使用 cglib 作为我的 spring 代理机制。问题是,我有一些 bean 的依赖项由构造函数注入(inject),我无法更改。 CGLIB 似乎不太喜欢这样,不会让我实例化那个 bean。有
当尝试将 CGLIB 与回调过滤器(在数万个对象上)一起使用时,我注意到速度很糟糕,但我无法找到有关优化 CGLIB 的任何信息。 对于搜索/列表界面,系统从优化的查询中加载多个属性,并使用这些属性填
我正在为生产 spring batch 项目构建端到端测试框架。我们想使用内存中的嵌入式数据库(在我们的例子中是 hsqldb)进行这些测试,因为它运行得更快并且没有环境限制。由于这些数据库引擎之间的
借助 cglib,我可以使用以下代码创建延迟实例化的 BigInteger: Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Bi
我有一个正在开发的 Java 库,它使用 cglib 创建库用户提供的抽象类的子类,并提供自动生成的用户留在其中的抽象方法的实现。 我的问题是,如果有问题的方法具有包本地(即默认)可访问性,我生成的方
我是一名优秀的程序员,十分优秀!