如何覆盖作用域的scoped bean?

时间:2013-02-04 17:56:27

标签: spring proxy scope javabeans

我的Spring Java配置中有这个bean:

@Bean
@Scope( proxyMode=ScopedProxyMode.TARGET_CLASS, value=SpringScopes.DESKTOP )
public BirtSession birtSession() {
    return new BirtSession();
}

对于测试,我需要一个没有范围的模拟(测试中没有“桌面”范围)。但是,当我为我的测试创建一个导入上述配置并包含:

的配置时
@Bean
public BirtSession birtSession() {
    return new MockSession();
}

我得到一个“桌面”范围的模拟bean: - (

如何让Spring“忘记”@Scope注释?

PS:当我不使用@Import并使用copy& paste但我不想这样做时,它可以正常工作。

2 个答案:

答案 0 :(得分:1)

问题似乎在ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod()中使用ScopedProxyCreator.createScopedProxy()静态方法来创建作用域bean定义:

// replace the original bean definition with the target one, if necessary
        BeanDefinition beanDefToRegister = beanDef;
        if (proxyMode != ScopedProxyMode.NO) {
            BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
                    new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS);
            beanDefToRegister = proxyDef.getBeanDefinition();
    }

BeanDefinitionHolder返回RootBeanDefinition而不是ConfiguratioClassBeanDenition时,另一个Java配置类不能覆盖作用域代理bean定义(即ScopedProxyFactoryBean)。

解决方法可能是声明要在xml配置文件中覆盖范围bean并使用@ImportResource.

导入它

答案 1 :(得分:0)

问题不在于Spring保留注释,问题在于Spring首先尝试解析"生产性"配置,为了做到这一点,它检查范围是否可用。 Spring急切地检查范围。所以它永远不会达到第二个/重写bean的定义。

创建虚拟范围:

import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.ObjectFactory;

public class MockSpringScope implements org.springframework.beans.factory.config.Scope {

    private Map<String, Object> objects = new HashMap<String, Object>();

    @Override
    public Object get( String name, ObjectFactory<?> objectFactory ) {
        Object result = objects.get( name );
        if( null == result ) {
            result = objectFactory.getObject();
            objects.put( name, result );
        }
        return result;
    }

    @Override
    public Object remove( String name ) {
        return objects.remove( name );
    }

    @Override
    public void registerDestructionCallback( String name, Runnable callback ) {
        // NOP
    }

    @Override
    public Object resolveContextualObject( String key ) {
        // NOP
        return null;
    }

    @Override
    public String getConversationId() {
        // NOP
        return null;
    }

}

并在&#34; Desktop&#34;下注册范围。那将是Spring允许成功解析生产配置。