Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
问Spring一个单例Bean的原型实例?_Spring_Grails_Groovy_Prototype_Singleton - Fatal编程技术网

问Spring一个单例Bean的原型实例?

问Spring一个单例Bean的原型实例?,spring,grails,groovy,prototype,singleton,Spring,Grails,Groovy,Prototype,Singleton,我有许多Grails服务是单例springbean,而不是原型 是否有任何方法可以检索通常是单例bean的原型实例(完全注入任何依赖项) 出于测试目的,我希望这样做,这样我就可以处理原型实例(可能会更改它的元类以模拟对象),而不会忘记在我对实例所做的任何更改之后进行清理,并让它们泄漏到其他测试中 我一直在玩弄这个,没有任何运气。我试过这样做: def ctx = grailsApplication.mainContext ctx.registerPrototype("foo", MyServi

我有许多Grails服务是单例springbean,而不是原型

是否有任何方法可以检索通常是单例bean的原型实例(完全注入任何依赖项)

出于测试目的,我希望这样做,这样我就可以处理原型实例(可能会更改它的元类以模拟对象),而不会忘记在我对实例所做的任何更改之后进行清理,并让它们泄漏到其他测试中

我一直在玩弄这个,没有任何运气。我试过这样做:

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上下文的建议两次让我找到了我想要的答案,目标是我想要原型版本的特定服务。最后创建了一篇博客文章,展示了一些额外的细节和测试功能: