gpt4 book ai didi

java - 使用 AOP 作用域代理在单例 bean 中 Autowiring 原型(prototype) bean

转载 作者:行者123 更新时间:2023-12-02 09:02:51 25 4
gpt4 key购买 nike

我能够测试在单例 bean 中 Autowiring 原型(prototype) bean 会导致仅创建一个原型(prototype) bean。

作为解决方案,我读到可以为原型(prototype) bean 定义 AOP 作用域代理或使用 Spring 的查找方法注入(inject)。

这是我尝试过的 -

PrototypeBean.java

@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.INTERFACES)
public class PrototypeBean implements Prototype {

private String welcomeMessage;

public String getWelcomeMessage() {
return welcomeMessage;
}

public void setWelcomeMessage(final String welcomeMessage) {
this.welcomeMessage = welcomeMessage;
}
}

SingletonBean.java

@Component
public class SingletonBean implements Singleton{
@Autowired private Prototype prototype;

public Prototype getPrototype() {
return prototype;
}

public void greet() {
System.out.println(prototype.getWelcomeMessage());
}
}

测试类

public class AutowiredDependenciesDemo {

@Autowired private Singleton autowiredSingleton;
@Autowired ConfigurableApplicationContext context;

@Test
public void testPrototypeBeanWithAopScopedProxy(){
Assert.assertNotNull(autowiredSingleton);

Prototype prototypeBean = (Prototype) ((SingletonBean) autowiredSingleton).getPrototype();
prototypeBean.setWelcomeMessage("hello world");

autowiredSingleton.greet();

Singleton contextSingleton = (Singleton) context.getBean("singletonBean");
Assert.assertSame(autowiredSingleton, contextSingleton);

Prototype anotherPrototypeBean = (Prototype) ((SingletonBean)contextSingleton).getPrototype();
anotherPrototypeBean.setWelcomeMessage("hello india");

contextSingleton.greet();
autowiredSingleton.greet();
// i expected both the prototype instances to be different. in the debugger, it does show two different 'proxied' instances. however the test fails.
Assert.assertNotSame(prototypeBean, anotherPrototypeBean);
}

我在这里遗漏了什么吗?另外,对greet()方法的调用返回null。

最佳答案

在考虑代理和原型(prototype) bean 时,您会混合一些东西。

当 Spring Framework 将 Prototype Scoped bean 注入(inject) Singleton Scoped bean 时,它会创建一个 Proxy 对象(实现所有必需的接口(interface))并注入(inject)它而不是 Prototype bean 的实例。然后,每当在此 Prototype Proxy 上调用方法时,Spring 都会创建一个新实例,并在此新实例上调用该方法。

在您的情况下 - 在测试中 - 您仅比较注入(inject)的代理,它们是相同的,因为原型(prototype) Bean 仅存在 1 个代理,并且此代理负责在需要时创建原型(prototype) Bean 的新实例。

这是我的例子:我有一个接口(interface) Prototype 及其实现 PrototypeImpl。在我的测试中,我直接从 ApplicationContext 获取 Prototype 类型的 bean,并且还使用 @Autowired 注入(inject)它。然后在调试器中我看到这个:

enter image description here

请注意,只有一个相同的代理(查看其地址),但在此代理上调用“toString()”会显示 PrototypeImpl 对象的两个不同地址。这准确地显示了我上面写的内容。

编辑:有关取消代理的信息

要扩展 M. Deinum 的评论,您可以通过以下方式从代理中提取底层对象:

Prototype extracted = null;

if(AopUtils.isAopProxy(a) && a instanceof Advised) {
Object target = ((Advised)a).getTargetSource().getTarget();
extracted = (Prototype) target;
}

关于java - 使用 AOP 作用域代理在单例 bean 中 Autowiring 原型(prototype) bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32295987/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com