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;
}
}
弹簧配置:
<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 的实例。不过,我会先玩调用二传手。
Spring 中是否有任何现成的解决方案可以用来实现:
Context initialized
before getting bean
after getting bean
calling add()...
NewClass()
setI(): 1
2
?