java – spring bean初始化依赖于其他bean的可变数量

在我的Spring / Grails / Groovy应用程序中,我配置了一些缓存bean:

rulesCache(InMemoryCache){..}
countriesCache(InMemoryCache){..}

myService(ServiceBean){
  cache = ref('rulesCache')
}

缓存管理器在检索缓存时提供专门的服务,因此我给管理器一个缓存bean列表:

cacheMgr(CacheManager){
  caches = [ ref('rulesCache'), ref('countriesCache')]
}

服务必须从管理器获取缓存bean,它们不能“连接”(管理器返回缓存委托,而不是缓存本身,这就是原因),所以我解决了这个问题:

  cacheMgr(CacheManager){
    caches = [ ref('rulesCache'), ref('countriesCache')]
  }

  cacheMgrDelegate(MethodInvokingFactoryBean) { bean ->
      bean.dependsOn = ['cacheMgr']
      targetObject = cacheMgr
      targetMethod = 'getManager'
   }

   myService(SomeService){
     cache = "#{cacheMgrDelegate.getCache('rulesCache')}"
   }

这工作正常,但缓存bean是任意的,所以我无法向管理器提供列表.我设法通过从缓存类型对象侦听post初始化事件,并通过管理器手动注册每个缓存来解决此问题:

CacheManager implements BeanPostProcessor {
    postProcessAfterInitialization(bean, beanName){
      if(bean instanceof ICache)
         registerCache(bean)
      return bean
    }
}

问题

问题是Spring在myManager上注册所有缓存bean之前在myService上进行初始化,因此getCache()返回null:

myService(SomeService){
   cache = "#{cacheMgrDelegate.getCache('rulesCache')}"
}

我明白为什么会这样.我不能使用dependsOn,因为缓存bean是任意的,这就是我被困住的地方.

可能解决方案

在Spring配置阶段,CacheManager.getCache(name)可以返回一个轻量级的“代理”类对象,同时保存对生成的每个代理的引用:

getCache(String name){
  CacheProxy proxy = createProxy()
  proxies.add(proxy)
  return proxy
}

配置完所有bean并设置应用程序上下文后,cacheManager只需迭代代理列表并完成初始化:

onApplicationContext(){
   proxies.each{ proxy ->
     completeInit(proxy)
   }
}

有更好的选择吗?我没有想法:-)

解决方法:

难道你不能简单地自动装配所有的ICache实例吗?它应该在CacheManager和缓存之间创建必要的依赖关系:

CacheManager {
    @Autowired
    public void setCaches(List<ICache> caches) {
        ...
    }
    ...
}

相关文章

背景:    8月29日,凌晨4点左右,某服务告警,其中一个...
https://support.smartbear.comeadyapi/docs/soapui/steps/g...
有几个选项可用于执行自定义JMeter脚本并扩展基线JMeter功能...
Scala和Java为静态语言,Groovy为动态语言Scala:函数式编程,...
出处:https://www.jianshu.com/p/ce6f8a1f66f4一、一些内部...
在运行groovy的junit方法时,报了这个错误:java.lang.Excep...