2014-11-14 83 views
0

我有一个使用Grails Redis插件的应用程序。这个插件工作正常,并且在我的Grails工件中提供了一个redisService。我也有一个单例CacheManager类,它具有一个静态实例变量,对redisSevice的引用。在Boostrap.groovyGrails BootStrap问题

class BootStrap { 

    def redisService 

    def init = { servletContext -> 
     CacheManager.instance.redisService = redisService 
    } 
    def destroy = { 
    } 
} 

class CacheManager { 

    def redisService 

    private static CacheManager manager = new CacheManager() 

    private CacheManager() { 
    } 

    public static CacheManager getInstance() { 
     manager 
    } 
} 

这一段时间工作正常,一段时间后,该redisService莫名其妙地变成空。我使用此缓存管理器作为redis上方的图层。我还没有找到更好的方法来将服务注入标准的POGO,所以这是有效的。它似乎在空闲了一段时间后失败了。

任何人都有一个想法,为什么?或者更好的主意?

回答

0

使用Holders访问redisServiceCacheManager似乎是一个更好的选择:

import grails.util.Holders 

class CacheManager { 

    def redisService = Holders.applicationContext.getBean("redisService") 

    (...) 

当你redisServiceCacheManager变空?是否在重新加载类时开发应用程序?或在'正常'运行的应用程序?第一种情况是,为什么就变成零了很好的解释,否则我不知道现在...

+0

你真的不应该使用'持有人'。通常当你发现自己到达“持有人”时,你需要暂停并问自己:“我真的在那里做正确的事情吗?”在你的情况下,答案是否定的。它应该是一个spring管理bean,你不应该使用'Holders'。 – 2014-11-15 10:05:08

+1

我不认为这是使用Holders的最好主意,而是最小的修改来提供示例工作。通常情况下,我宁愿将'CacheManager'定义为bean,正如你在答案中所建议的那样。无论如何,感谢您的良好解释和建议:) – 2014-11-15 10:09:46

+0

你更欢迎。乐意效劳。将提供的示例移动到'Resources.groovy'中的Spring托管bean实际上会减少代码的数量(例如,从bootstrap中删除的所有内容以及添加到资源中的一行或两行)。 :) – 2014-11-15 10:11:48

0

事实上,定义CacheManager作为内部Resources.groovy真实弹簧豆会做到这一点bestcorrect方式。这样做也可能会避免您在参考变为null时遇到的任何问题。

+0

谢谢大家。我仍然不确定我是否有可以使用的答案。我的主要问题是从pogos中访问我的CacheManager,这些命令实际上是Hystrix命令。所以没有自动注射。 redisService是一个单例。 CacheManager也是一个单身人士。 – 2014-11-16 17:07:08

+0

达恩手机自动更正。 CacheManager也是一个Singleton。如果我将它变成Spring托管bean,那么如何在Hystrix命令对象中访问它,而不使用Holders? – 2014-11-16 17:14:45