问Spring一个单例Bean的原型实例?
我有许多Grails服务是单例springbean,而不是原型 是否有任何方法可以检索通常是单例bean的原型实例(完全注入任何依赖项) 出于测试目的,我希望这样做,这样我就可以处理原型实例(可能会更改它的元类以模拟对象),而不会忘记在我对实例所做的任何更改之后进行清理,并让它们泄漏到其他测试中 我一直在玩弄这个,没有任何运气。我试过这样做:问Spring一个单例Bean的原型实例?,spring,grails,groovy,prototype,singleton,Spring,Grails,Groovy,Prototype,Singleton,我有许多Grails服务是单例springbean,而不是原型 是否有任何方法可以检索通常是单例bean的原型实例(完全注入任何依赖项) 出于测试目的,我希望这样做,这样我就可以处理原型实例(可能会更改它的元类以模拟对象),而不会忘记在我对实例所做的任何更改之后进行清理,并让它们泄漏到其他测试中 我一直在玩弄这个,没有任何运气。我试过这样做: def ctx = grailsApplication.mainContext ctx.registerPrototype("foo", MyServi
def ctx = grailsApplication.mainContext
ctx.registerPrototype("foo", MyService)
然后我可以向Spring请求MyService
def myServicePrototype = ctx.getBean("foo")
它每次都会给出一个新实例,但是没有一个实例的属性自动连接,所以它们都是空的。我猜有一些方法可以创建一个BeanDefinition,并将它提供给BeanFactory,同时启用一些我必须缺少的autowire功能
我希望能想出一些通用的解决方案,不会强迫我以任何方式显式地注释目标服务
有没有办法直接向Spring applicationContext询问通常是单例的原型版本?如果只是为了测试目的,并且没有冲突的依赖项(例如,某些bean必须是单例),那么您可以只创建两次Spring上下文
编辑:另一个建议是为单例服务定义一个工厂接口,并提供该工厂接口的两个实现:1个仅用于单例,第二个用于具有多个实例,具体取决于您的测试情况 了解了如何使用Grails BeanBuilder创建一个临时应用程序上下文,该上下文将主应用程序上下文作为父应用程序上下文。如果对服务进行了任何不寻常的连线/spring配置,这将不起作用,但Grails服务通常不是这样,因此这似乎是一种很好的默认模式:
// this works in the grails console where grailsApplication is in the binding,
// need to inject in other situations
import org.springframework.context.ApplicationContext
import grails.spring.BeanBuilder
import com.example.service.MyService
def getPrototypeInstanceOf(Class clazz) {
BeanBuilder beanBuilder = new BeanBuilder(grailsApplication.mainContext)
String beanName = "prototype${clazz.name}"
beanBuilder.beans {
"$beanName"(clazz) { bean ->
bean.autowire = 'byName'
}
}
ApplicationContext applicationContext = beanBuilder.createApplicationContext()
return applicationContext.getBean(beanName)
}
def prototypeService = getPrototypeInstanceOf(MyService)
def singletonService = grailsApplication.mainContext.getBean("myService")
assert singletonService != prototypeService
assert singletonService.injectedService == prototypeService.injectedService
或者,有没有办法从spring的singleton缓存中销毁/删除现有的singleton,并让
getBean(“myService”)
重新生成/重新自动连接该服务的新实例?感谢您的回复,您关于创建spring上下文的建议两次让我找到了我想要的答案,目标是我想要原型版本的特定服务。最后创建了一篇博客文章,展示了一些额外的细节和测试功能: