当我们使用自定义 spring 范围时,我们有一个产品 - 'tenant'。 它与我们的系统架构密切相关。
在产品上线期间,我们决定放弃这个范围,但我们真的不想破坏向后兼容性。 换句话说,我们希望现有的产品实现开始时不会出现错误,例如:
Initialization of bean failed; nested exception is java.lang.IllegalStateException: No Scope registered for scope 'tenant'
我们也不想更正任何在 spring 配置或任何 java 类中出现的租户定义(发生 @Scope("tenant")
的地方)。
我们在使用自定义加载 bean 定义时设法忽略了作用域
XmlBeanDefinitionReader
我们似乎缺少过滤任何 bean 创建(任何 BeanDefinition )并忽略作用域的一般概念 - 用 Singleton 替换它。
这是代码
这是覆盖范围的代码:
new ReaderEventListener()
{<p></p>
@Override
public void importProcessed(final ImportDefinition importDefinition)
{
//
}
@Override
public void defaultsRegistered(final DefaultsDefinition defaultsDefinition)
{
//
}
@Override
public void componentRegistered(final ComponentDefinition componentDefinition)
{
for (final BeanDefinition beanDefinition : componentDefinition.getBeanDefinitions())
{
if ("tenant".equalsIgnoreCase(beanDefinition.getScope()))
{
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
if (LOG.isDebugEnabled())
{
LOG.debug("Adjusting bean defintion for " + beanDefinition
+ " - ignoring tenant scope - please modify it manually to avoid confussion.");
}
}
}
for (final BeanDefinition beanDefinition : componentDefinition.getInnerBeanDefinitions())
{
if ("tenant".equalsIgnoreCase(beanDefinition.getScope()))
{
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
if (LOG.isDebugEnabled())
{
LOG.debug("Adjusting bean defintion for " + beanDefinition
+ " - ignoring tenant scope - please modify it manually to avoid confussion.");
}
}
}
}
@Override
public void aliasRegistered(final AliasDefinition aliasDefinition)
{
//
}
}); <code>
看起来它在大多数情况下都有效,但以下情况除外: 精确的 正则表达式 以。。开始 以。。结束 包含 看起来它能够更改包装的范围租户
org.springframework.beans.factory.config.ListFactoryBean
但不适用于底层 beans ....
值得一提的是,我们逐个加载包含我们自己的 bean 定义的文件。
最佳答案
您可以注册租户范围并将其实现为单例吗?
public class TenantScopeMock implements Scope {
@Autowired private ApplicationContext appContext;
public Object get(final String name, final ObjectFactory objectFactory) {
if (!appContext.containsBean(name))
((SingletonBeanRegistry)appContext.getBeanFactory()).registerSingleton(name, objectFactory.getObject());
return appContext.getBean(name);
}
public String getConversationId() {
return null;
}
public void registerDestructionCallback(final String theName, final Runnable callback) {
}
public Object resolveContextualObject(String key) {
return null;
}
public Object remove(final String theName) {
return null;
}
}
并注册:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="tenant">
<bean class="mypackage.TenantScopeMock" />
</entry>
</map>
</property>
</bean>
关于spring - 如何忽略自定义 Spring 租户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13155472/