弹簧&x27;s Javaconfig和原型bean

弹簧&x27;s Javaconfig和原型bean,java,spring,Java,Spring,我已经将代码从Spring的XML配置移动到Java配置。我所有的东西都在工作,但我有一个关于我如何实现原型bean的问题——主要是,当我所做的工作起作用时,这是最好的方法吗?不知怎么的,它只是感觉不舒服 我这样编写bean类: @Component @Scope("prototype") public class ProtoBean { ... } 然后使用bean——这是我不确定的部分,尽管它确实有效: @Component public class BeanUser implem

我已经将代码从Spring的XML配置移动到Java配置。我所有的东西都在工作,但我有一个关于我如何实现原型bean的问题——主要是,当我所做的工作起作用时,这是最好的方法吗?不知怎么的,它只是感觉不舒服

我这样编写bean类:

@Component
@Scope("prototype")
public class ProtoBean {
    ...
}
然后使用bean——这是我不确定的部分,尽管它确实有效:

@Component
public class BeanUser implements ApplicationContextAware {
    ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext context)throws BeansException
    {
        this.context = context;
    }

    public void getProtoBean() {
         ProtoBean protoBean = context.getBean(ProtoBean.class);
    }
}
这就得到了一个原型bean,在单元测试中,我只是模拟了上下文,用mock调用了setApplicationContext,并让mock的getBean调用返回一个mock原型bean。所以一切都很好

我通过使用工厂在XML中实现了这一点,但这似乎效果不太好,所以我就这样结束了。但是有没有一种方法可以在没有上下文的情况下做到这一点呢?还是一个更好的方法


谢谢

我不认为springxml与Java基本配置之间存在太多的问题,而是匹配依赖范围的问题。由于Spring在创建时只能对单例范围的bean进行依赖注入,因此必须根据需要查找原型范围的bean。当然,当前的bean查找方法是有效的,但会创建对ApplicationContext的依赖。我可以提出一些其他的可能性,但问题的根源实际上是生产ProtoBean涉及到什么,以及您应该接受什么样的权衡

您可以将BeanUser本身的原型范围设置为作用域,这将允许您将ProtoBean作为成员进行连接。当然,取舍是您现在在BeanUser的客户机上也有同样的问题,但有时这不是问题

另一种方法是使用类似于单例作用域ProtoBeanFactory的东西来提供ProtoBean实例,并在ProtoBeanFactory中隐藏依赖项查找

最后,您可以使用作用域代理bean来有效地隐藏工厂。它使用AOP来实现这一点,而其他人并不总是清楚你使用的是哪种巫毒。对于XML,您可以在bean声明中使用
。对于您将使用的注释:

@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS, value = "prototype")

此时您没有使用基于Java的配置。看看这里,这是一个有趣的链接-谢谢。我使用@ComponentScan在我的java配置类中发现了这一点,因此它的工作方式似乎与之类似,有趣的是,这与他们在链接中给出的第一个如何实现这一点的示例相匹配——但随后他们继续讨论“方法注入”,这似乎是他们建议的解决方案。非常感谢。