0

I've moved my code from Spring's XML configuration to Java Configuration. I have everything working, but I have a question about how I implemented prototype beans - mainly, while what I'm doing works, is it the best way to do this? Somehow it just feels off!

I wrote the bean class this way:

@Component
@Scope("prototype")
public class ProtoBean {
    ...
}

Then to use the bean - this is the part that I'm just not sure about, although it does work:

@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);
    }
}

This gets me a prototyped bean, and in unit tests I just mocked the context, called setApplicationContext with the mock, and had the getBean call of the mock return a mock ProtoBean. So all is well.

I did this in the XML by using a factory, but that didn't seem to work too well, so this is where I ended up. But is there a way to do this without the context? Or just a better way?

Thanks!

4

1 回答 1

1

我不认为 Spring XML 与基于 Java 的配置之间存在这么大的问题,而是匹配的依赖范围之一。由于 Spring 只能在创建时对单例范围的 bean 进行依赖注入,因此您必须按需查找原型范围的 bean。当然,当前的 bean-lookup 方法可以工作,但是会创建对 ApplicationContext 的依赖。我可以提出其他一些可能性,但问题的根源实际上是生产 ProtoBean 所涉及的内容,以及您应该接受哪些取舍。

您可以将 BeanUser 本身设置为原型范围,这将允许您将 ProtoBean 作为成员进行连接。当然,权衡是您现在在 BeanUser 的客户端上遇到了同样的问题,但有时这不是问题。

另一个路径可能是使用类似单例范围的 ProtoBeanFactory 来提供 ProtoBean 实例,并在 ProtoBeanFactory 中隐藏依赖项查找。

最后,您可以使用作用域代理 bean 来有效地隐藏工厂。它使用 AOP 来做到这一点,并且并不总是让其他人清楚你正在使用哪种巫术。使用 XML,您将<aop:scoped-proxy/>在 bean 声明中使用。对于您将使用的注释:

@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS, value = "prototype")
于 2013-07-18T22:50:04.537 回答