そのクラスのメソッドが呼び出されたときにクラスが CREATED (新しいインスタンス) および INITIALIZED (セッターが呼び出される) になるように、クラスをプロキシするためのすぐに使用できるソリューションが Spring にありますか?
org.springframework.aop.target.LazyInitTargetSource を見つけて使ってみました。
たぶん私は何か間違ったことをしているのですが、次のシナリオではクラスインスタンスが 2 回作成されています。Bean がコンテキストから取得されたときに 1 回、次にメソッドが呼び出されたときにもう一度:
私のプロキシクラス:
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 が要求されたときにプロキシがプロキシされたクラスのインスタンスを作成するようです。それは私が望むものではありません。
NewClass のホルダーとして独自の java.lang.reflect.Proxy を作成し、メソッドが最初に呼び出されたときにハンドラーの invoke() で NewClass のインスタンスを作成できます。ただし、最初にセッターを呼び出すことで遊んでいたでしょう。
私が達成するために使用できるSpringの準備が整ったソリューションはありますか?
Context initialized
before getting bean
after getting bean
calling add()...
NewClass()
setI(): 1
2
?