Usando il metodo di iniezione rende la classe Singleton-bean difficile unità-test (è necessario creare una sottoclasse di implementare il metodo che dà la dipendenza). Inoltre è meno riutilizzabile perché non è possibile creare un'istanza immediata, quindi se non si utilizza Spring e si desidera utilizzare questa classe, sarà necessario creare una sottoclasse e fornire il metodo di restituzione dei bean.
Un approccio migliore IMHO consiste nell'utilizzare un proxy, un prototipo di origine di destinazione e un prototipo di bean di destinazione, come segue. Tale classe di bean singleton è facilmente testata da unità e riutilizzabile meglio.
<bean id="targetPooledObject" class="pool.PooledObject" scope="prototype">
<constructor-arg value="42" />
</bean>
<bean id="prototypeTargetSource" class="org.springframework.aop.target.PrototypeTargetSource">
<property name="targetBeanName" value="targetPooledObject" />
</bean>
<bean id="pooledObject" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource" ref="prototypeTargetSource" />
</bean>
<bean id="poolConsumer" class="pool.PoolConsumer">
<property name="pooledObject" ref="pooledObject" />
</bean>
Ora si può iniettare pooledObject
in un bean singleton (poolConsumer
come mostrato sopra), e per ogni chiamata di metodo che facciamo su tale fagiolo singoletto, (ad esempio, ogni volta che chiamiamo poolConsumer.callPooledObjectMethod()
che a sua volta richiama pooledObject.foo()
) abbiamo ottenere un nuovo bean PooledObject.
seguito è il codice corrispondente:
public class PooledObject
{
private int x;
public PooledObject(int x)
{
this.x = x;
}
public void foo()
{
System.out.println("foo called");
}
}
public class PoolConsumer
{
private PooledObject pooledObject;
public PooledObject getPooledObject()
{
return pooledObject;
}
public void setPooledObject(PooledObject pooledObject)
{
this.pooledObject = pooledObject;
}
public void callPooledObjectMethod()
{
pooledObject.foo();
}
}
Questa risposta è obsoleta, come ha detto Christopher, poiché Spring 3.0 l'elemento ' ' è il modo giusto per farlo. Inoltre, come sottolineato da shrini1000, l'iniezione di metodi rende la classe goffa da testare. –