gpt4 book ai didi

java - 在 Spring 中通过代理创建和初始化惰性类实例

转载 作者:行者123 更新时间:2023-11-30 09:35:52 25 4
gpt4 key购买 nike

Spring 中是否有现成的开箱即用解决方案来代理类,以便在调用该类的方法时创建(新实例)和初始化(调用 setter)?

我发现并尝试使用 org.springframework.aop.target.LazyInitTargetSource。

也许我做错了什么,但在下面的场景中,我的类实例创建了两次。一旦从上下文中检索到 bean,然后在调用方法时再次调用一次:

我的代理类:

public class NewClass {

private Integer i;

public NewClass() {
System.out.println("NewClass()");
}

public void setI(Integer i) {
System.out.println("setI(): " + i);
this.i = i;
}

public Integer add() {
return i + 1;
}
}

Spring 配置:

<bean id="newClassTarget" class="com.mycompany.spring.NewClass" lazy-init="true">
<property name="i" value="1"/>
</bean>

<bean id="newClass" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource">
<bean class="org.springframework.aop.target.LazyInitTargetSource">
<property name="targetBeanName">
<idref local="newClassTarget"/>
</property>
</bean>
</property>
</bean>

运行代码:

public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("lazy.xml");
System.out.println("Context initialized");
System.out.println("before getting bean");
NewClass newClass = (NewClass) applicationContext.getBean("newClass");
System.out.println("after getting bean");
System.out.println("calling add()...");
System.out.println(newClass.add());
}

产生:

Context initialized
before getting bean
NewClass()
after getting bean
calling add()...
NewClass()
setI(): 1
2

因此,当从 Spring 上下文获取 bean 并调用 add() 方法时,将调用 NewClass 构造函数。我觉得这不太好,我是不是搞砸了什么?

无论如何,第一个调用来自Cglib2AopProxy.getProxy()中的enhancer.create()。似乎代理在请求 bean 时创建代理类的实例,而不是在第一个方法调用发生时。这不是我想要的。

我可以创建自己的 java.lang.reflect.Proxy 作为我的 NewClass 的持有者,并在第一次调用方法时在处理程序的 invoke() 中创建 NewClass 的实例。不过,我会先尝试调用 setter。

Spring 中是否有现成的解决方案可以用来实现:

Context initialized
before getting bean
after getting bean
calling add()...
NewClass()
setI(): 1
2

?

最佳答案

我能够复制您的行为 - 我的解决方法是简单地为您的 NewClass 定义一个接口(interface),这样就创建了 Java 动态代理而不是 CGLIB 增强代理。然后它按预期工作 - 在调用方法时实例化 NewClass。

public interface NewInterface {
public void setI(Integer i);
public Integer add() ;
}

public class NewClass implements NewInterface{

private Integer i;

public NewClass() {
System.out.println("NewClass()");
}

public void setI(Integer i) {
System.out.println("setI(): " + i);
this.i = i;
}

public Integer add() {
return i + 1;
}
}

关于java - 在 Spring 中通过代理创建和初始化惰性类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11097369/

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