gpt4 book ai didi

java - Spring Scoped Proxy 适用于 Scoped Proxy Beans 字段的字段而不是 beans 本身?

转载 作者:行者123 更新时间:2023-11-29 04:53:53 24 4
gpt4 key购买 nike

这是我的代码:

Spring 配置:

package biz.tugay;
/* User: koray@tugay.biz Date: 25/12/15 Time: 19:30 */

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "biz.tugay")
public class SpringConfiguration {
}

富:

package biz.tugay;
/* User: koray@tugay.biz Date: 25/12/15 Time: 19:36 */

public interface Foo {
String getState();
}

FooImpl:

package biz.tugay;
/* User: koray@tugay.biz Date: 25/12/15 Time: 19:31 */

import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;

import java.util.UUID;

@Component
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class FooImpl implements Foo {
private final String state = UUID.randomUUID().toString();
public String getState() {
return state;
}
}

酒吧:

package biz.tugay;
/* User: koray@tugay.biz Date: 25/12/15 Time: 19:35 */

public interface Bar {
Foo getFoo();
}

BarImpl:

package biz.tugay;
/* User: koray@tugay.biz Date: 25/12/15 Time: 19:33 */

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope(value = "singleton")
public class BarImpl implements Bar {

private Foo foo;

@Autowired
public void setFoo(Foo foo) {
this.foo = foo;
}

public Foo getFoo() {
return foo;
}
}

和测试类:

package biz.tugay;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import static java.lang.System.out;

public class TestClass {

final static Class<SpringConfiguration> SPRING_CONFIGURATION_CLASS = SpringConfiguration.class;

public static void main(String[] args) {

final ApplicationContext applicationContext;
applicationContext = new AnnotationConfigApplicationContext(SPRING_CONFIGURATION_CLASS);

final Bar barOne = applicationContext.getBean(BarImpl.class);
final Bar barTwo = applicationContext.getBean(BarImpl.class);

out.println("barOne == barTwo: " + (barOne == barTwo));
out.println("barOne.getFoo == barTwo.getFoo: " + (barOne.getFoo() == barTwo.getFoo()));

out.println(barOne.getFoo().getState());
out.println(barTwo.getFoo().getState());

}
}

输出将是:

barOne == barTwo: true
barOne.getFoo == barTwo.getFoo: true
064bdb74-cad7-4d13-86fe-a4fc0021e5a0
c6f2d9be-09b4-456d-9414-8ece2f2acc9e

我的问题是,

我知道 064bdb74-cad7-4d13-86fe-a4fc0021e5a0 不等于 c6f2d9be-09b4-456d-9414-8ece2f2acc9e 因为 FooImpl 实际上是 ScopedProxy。

我不明白的是,为什么barOne.getFoo可以等于barTwo.getFoo?

这怎么可能:

barOne.getFoo() == barTwo.getFoo()
barOne.getFoo().getState() != barTwo().getFoo().getState()

???

最佳答案

要首先理解输出,您需要了解 Spring Framework 的工作方式和内容。让我们从以下想法开始:当您将“短期”作用域 bean 注入(inject)“长期”作用域 bean(在您的例子中,原型(prototype) bean 注入(inject)单例 bean)时,Spring 会注入(inject)一个 AOP 代理来代替作用域 bean。

That is, you need to inject a proxy object that exposes the same public interface as the scoped object but that can also retrieve the real target object from the relevant scope (such as an HTTP request) and delegate method calls onto the real object.

基本上有两种主要类型的代理,JDK 代理和 CGLIB 代理(默认)。

所以让我们回到示例代码并尝试理解发生了什么......当您的应用程序启动时,Spring Framework 会创建两个 bean FooBar,但这两个 bean 不仅仅是一个简单的实现(FooImpl 和 BarImpl),而是代理(CglibAopProxy 的)。因此,在您的 TestClass 类中,您有 2 个对 BarImpl barOne 和 barTwo 的相同 AopProxy 的引用。由于 Bar 的作用域为单例,因此 AopProxy 的底层目标类是相同的对象 (BarImpl),它已预先初始化。而这个 Bar AopProxy 有一个 Foo 类型的注入(inject) AopPorxy,所以当你执行下面的代码时 barOne.getFoo() == barTwo.getFoo() 它的计算结果为真,因为 barOnebarTwo 具有相同的 AopProxy 实例(不是目标类),但是当您调用 barTwo( ).getFoo().getState() AopProxy 正在创建目标类 (FooImpl) 的新实例并在其上执行 getState() 方法。所以每次调用 bar.getFoo().getState() 都会创建一个新的 FooImpl 实例,然后执行它的 getState() 方法.

关于java - Spring Scoped Proxy 适用于 Scoped Proxy Beans 字段的字段而不是 beans 本身?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34469967/

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