任何人都知道除Servlet Context Scope和ThreadScope之外的任何其他自定义弹簧范围?
如果您已经制作了一些闭源自定义示波器,我真的也有兴趣了解它的作用以及它是如何为您制作的。 (我想有人会在桌面应用程序中制作一个WindowScope?)
我对所有用例持开放态度,我希望在这里拓展视野。
答案 0 :(得分:9)
我们实现了自己的自定义Spring范围。我们的许多代码都在相对较低的层次上工作,靠近数据库,并且我们使用自己的数据源,链接,属性等对象模型来维护概念级别。
无论如何,很多bean需要一个所谓的StorageDictionary(这个对象图的封装)来完成他们的工作。当我们对对象图进行非平凡的更改时,有时需要将字典吹走并重新创建。因此,我们为字典范围的对象实现了自定义范围,并且给定字典的无效部分涉及清除此自定义范围。这让Spring为这些对象处理了一种很好的自动缓存形式。每次都会得到相同的对象,直到字典失效,此时你会得到一个新对象。
这不仅有助于一致性,而且还允许对象本身缓存对字典中实体的引用,只要它们本身可由Spring检索,就可以安全地知道缓存有效。这反过来让我们将它们构建为不可变对象(只要它们可以通过构造函数注入进行连接),这在任何可能的情况下都是非常好的事情。
这种技术无处不在,并且在很大程度上取决于软件的特性(例如,如果字典经常被修改,这将是非常低效的,如果它被更新,从来没有这将是不必要的,效率略低于直接访问)。但是,它确实帮助我们以一种概念上简单明了的方式将生命周期管理权交给Spring,在我看来非常优雅。
答案 1 :(得分:4)
在我的公司,我们创建了两个自定义范围,一个将使用Thread或Request,另一个将使用Thread或Session。我们的想法是,可以将单个作用域用于作用域bean,而无需根据执行环境(JUnit或Servlet容器)更改配置。当您在Quartz中运行项目并且不再具有Request或Session范围时,这也非常方便。
答案 2 :(得分:4)
背景:
我在一个Web应用程序上工作,该应用程序在同一个servlet上下文中运行4个不同的Web站点。每个站点都有自己的域名,例如www.examplesite1.com,www.examplesite2.com等
问题:
站点有时需要从应用程序上下文中自定义bean的自定义实例(通常用于自定义的消息显示或对象的格式化)。
例如,假设站点1和站点2都使用“standardDateFormatter”bean,站点3使用“usDateFormatter”bean,站点4使用“ukDateFormatter”bean。
解决方案:
我打算使用“网站”范围。
我们有这样的网站枚举:
enum Site {
SITE1, SITE2, SITE3, SITE4;
}
然后我们有一个过滤器,使用ThreadLocal在请求的线程中存储其中一个Site值。这是网站范围的“会话ID”。
然后在app上下文中有一个名为“dateFormatter”的bean,其中“scope =”site“'。然后,无论我们想要使用日期格式化程序,都将使用用户当前站点的正确格式。
稍后添加:
示例代码:
答案 3 :(得分:2)
Oracle Coherence已实施datagrid scope for Spring beans。总结一下:
数据网格Bean 是a的代理 java.io.Serializable Bean实例 存储在非过期的 Coherence分布式缓存(称为 近datagridbeans)。
我自己从未使用它们,但它们看起来很酷。
答案 4 :(得分:2)
Apache Orchestra提供SpringConversationScope。
答案 5 :(得分:1)
在Spring Batch应用程序中,我们实现了项目范围。
我们有很多@Service
个组件,可根据当前批次项计算某些内容。他们中的许多人需要相同的工作流程:
我们将工作流移动到基类模板方法中,因此子类仅实现findItemParts(Item)
(执行1和2)和computeSomething(ItemPart)
(执行3)。所以它们变为有状态(在findItemParts
中需要在computeSomething
中初始化的东西),并且必须在下一个项目之前清除该状态。
其中一些服务还涉及注入的Spring bean,它们也来自当前项目,之后必须删除。
我们实现了AbstractScopeRegisteringItemProcessor
注册项目并允许子类注册派生bean。在process
方法的末尾,它使用DefaultSingletonBeanRegistry.destroySingleton
从其范围上下文和派生的bean中删除该项。
它有效,但有以下问题:
@Scope
)。具体的处理器必须创建并注册它们。AbstractScopeRegisteringItemProcessor
可以更好地使用组合并动态实现底层处理器的所有接口。但是生成的@StepScope
bean是declared return type(即AbstractScopeRegisteringItemProcessor
或ItemProcessor
)的代理,没有所需的回调接口。在@Eliot Sykes的solution和共享代码以及@ Cheetah BeanDefinition registration的帮助下,我能够将注册视为单身豆。相反,ItemScopeContext
(处理器和Scope
实现使用的存储;通过静态@Bean
方法配置的Java)实现BeanDefinitionRegistryPostProcessor
。它注册一个FactoryBean
,getObject()
返回当前项,如果没有,则抛出异常。现在,用@Component
注释的@Scope(scopeName = "Item", proxyMode = ScopedProxyMode.TARGET_CLASS)
可以简单地注入该项目,无需注册进行范围最终清理。
所以最后,它确实运作良好。
答案 6 :(得分:0)
基于Web应用程序中用户区域设置的弹出区域设置范围
答案 7 :(得分:0)
在我的公司,我们还实施了弹簧自定义范围。我们有一个多租户系统,每个客户都可以自定义设置。基于实例的范围,缓存客户特定的bean。因此,每次客户的用户登录时,这些设置都会被缓存,并在同一客户的其他用户登录时重新使用。
答案 8 :(得分:0)
我曾经使用一种会话范围在会话范围内存储一些对象,以便在重新进入同一页面时保留它们,但仅限于单页以避免离开会话中无用的对象。该实现只是存储了页面URL并在每次更改页面时清除了会话范围。