我有一个单身人士spring bean(并且必须保留一个单例),每当执行某个方法时,它需要另一个bean的新实例(我们称其为x)。
到目前为止,我查看了以下方法:
-
只需使用新创建X即可。这持续了一段时间,但是现在我们需要X的Spring AOP功能,因此这不再起作用,因为所产生的实例不受弹簧的管理。
-
我将工厂视为依赖性,但我只会从FactoryBean中获得一个X实例,该实例不符合我的第一个实例。
-
当前的计划是在春季上下文中手动查找X,并以原型依赖性声明它。这应该起作用,但我认为这确实很丑。
=>我如何在豆子中注入工厂,以便每当我认为合适并从中获得一个弹簧托管实例时可以调用其工厂方法。
这样的方案的选择手段称为查找方法注入。简而言之,这使用了对Bean方法调用的方法,从而导致创建了新的BEAN实例。首先,您将使用抽象方法创建一个类,该方法最终将提供依赖项实例:
abstract class MyClient implements Client {
void businessMethod(…) {
Dependency dependency = getDependencyInstance();
…
}
abstract Dependency getDependencyInstance();
}
您现在继续并为依赖项配置原型bean定义:
<bean id="dependency" class="….DependencyImpl" scope="prototype" />
以及使用lookup-method
元素的客户端始终获取每个方法的依赖关系的新实例:
<bean class="….MyClient">
<lookup-method name="getDependencyInstance" bean="dependency" />
</bean>
这将导致为MyClient
创建一个CGLIB代理,并且getDependencyInstance(…)
的方法声明由TargetSource
支持,并引用了BeanFactory
和要查找的bean的名称。在每种方法调用上,将触发bean查找,并返回原型bean的新实例。
我看不到工厂豆的问题,我会这样做:
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
@Component
public class X {
public static class XFactory implements FactoryBean<X> {
@Override
public X getObject() throws Exception {
return new X();
}
@Override
public Class<?> getObjectType() {
return X.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
}
并注入此工厂豆。
否则,您可以使用
来调整X Bean@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS, value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
您必须使用非默认代理模式,以便Spring创建一个代理,该代理总是将新实例返回您的Singleton。
如果您使用XML配置,那么它还是这样做的:
<bean id="x" class="X" scope="prototype">
<aop:scoped-proxy>
</bean>
玩得开心。
编辑:
当您通过@component注释工厂(我已经添加了上面)时,请返回#issingleton中的false,并确保您不返回X两次,可以将@Autowired的Factory Bean注入您的Singleton中。<<<<<<<<<<<<<<<<<<<<<<<</p>
否则我只是检查了
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
@Component
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class X {
}
它可以按预期工作。
编辑2:
如果您不想注入工厂bean,但只想注入依赖性,您可以原型范围范围(@scope(proxymode = scopedproxymode.target_class_class),value value =" prototype"),但除了新的工厂是每次都涉及X时创建,这可能不是您想要的。
如果您不希望工厂本身注入Olivers查找方法。