@Component
@Scope("prototype")
public class MessageHandller {
.........................
private static ConcurrentMap<String, Boolean> someObjectList = new ConcurrentHashMap<>();
....................................
@Scheduled(fixedDelayString = "60000")
public static void doSomething() {
if(***) {
someObjectList.add(**);
} else {
someObjectList.remove(**);
}
}
}
那就说我有Class MessageHandller,它是带有Prototype范围的Spring Bean。在这个课程中我有预定的方法&#34; doSomething&#34;每60000毫秒运行一次。
我认为Scheduled方法可能会导致内存泄漏,因为它总是会对MessageHandler类进行引用,这是&#34; prototype&#34;范围,这意味着GC永远不会收集它?如果我错了,有人可以解释一下吗?
答案 0 :(得分:0)
您必须明确区分使用@Schedule注释的方法和bean本身,当您注释方法并通过@EnableScheduling或xml替代启用调度功能时,spring将使用托管bean查找和搜索带注释的方法(注释为@Compenont,@ Service ...)在doc
中提及如果您阅读有关Bean处理器ScheduledAnnotationBeanPostProcessor的信息。你会注意到它没有涉及这个过程的范围,并且无论bean父级的范围如何,TaskScheduler
都会调用该方法
现在对于原型bean,文档提到:
与其他作用域相比,Spring不管理原型bean的完整生命周期:容器实例化,配置和组装原型对象,并将其交给客户端,没有该原型实例的进一步记录。因此,尽管无论范围如何都在所有对象上调用初始化生命周期回调方法,但在原型的情况下,不会调用已配置的销毁生命周期回调。客户端代码必须清理原型范围的对象并释放原型bean所持有的昂贵资源
因此,当没有对原型对象的引用时,它将像任何new object()
隐式地被垃圾收集器一样销毁
为了清楚表明schedule方法的行为的生命周期与声明的bean不同,因为它的实现被其他bean管理器使用,就像TaskScheduler
为此目的的任何{{1}}实现一样,< / p>
干杯