|
From: Colin S. <col...@ex...> - 2003-12-08 16:16:32
|
Hey Roger,
This is quite interesting. I started implementing something (fairly
similar to your approach, although more simplistic) but ran out of
time, so in the meantime just kept on using BeanFactory.getBean in the
couple of cases where I would have used this.
I'll take a look at this in more depth on the weekend. This is
definitely useful to people using Spring. The only real question is if
it's useful to enough people to warrant including in the core, given the
size.
Regards.
Colin
roger holbrook wrote:
>Colin,
>
>A long delayed response, but just in case this topic may still be of
>interest to you...
>
>I played around with a couple of ways of doing this, & have attached a
>straight forward implementation of the initial scheme that you first
>outlined, ie: given the following:
>
>public interface ITestBean_Factory1 {
> ITestBean getInstance();
>}
>
><bean id="testBean"
> class="org.springframework.beans.TestBean">
> <property ... >
></bean>
>
><bean id="testTypedFactoryBean1"
> class="org.springframework.beans.factory.support.TypedFactoryBean">
> <property name="interface">
> <value>
> org.springframework.beans.factory.support.ITestBean_Factory1
> </value>
> </property>
> <property name="target">
> <value>
> testBean
> </value>
> </property>
></bean>
>
>then a call to beanFactory.getBean("testTypedFactoryBean1") will return
>dynamic proxy instance that implements the given typed factory interface.
>
>
>FYI, the following is a short description of the 'other' approach I tried:
>
>My first thought was that your initial scheme could be simplified by using
>a factory-interface attribute on the target bean definition, & doing away
>with the need to have a separate typed factory bean, ie:
>
><bean id="testBean"
> class="org.springframework.beans.TestBean">
>factory-interface"org.springframework.beans.factory.support.ITestBean_Factor
>y1"
> <property... >
></bean>
>
>With a few tweaks in core classes, this all works fine - the only problem is
>that it just doesn't feel clean enough, ie: it requires the following things
>to change:
>
>- new factory-interface bean definition attribute
>- new behaviour for beanFactory.getBean("&beanName"), since the typed
>factory dynamic proxy instance returned, will no longer reliably be an
>instance of FactoryBean
>- small, but none the less, additional complexity to AbstractBeanFactory,
>one more level of indirection to contend with
>
>On reflection, in this instance, end of idea ;)
>
>I would be interested to know how you ended up actually dealing with the
>issue in practice ?
>
>Roger
>
>
>
>"Colin Sampaleanu" <col...@ex...> wrote in message
>news:3FB...@ex......
>
>
>>I was thinking of the first, with the idea that there is no Spring class
>>dependency, and you achieve total inversion of control.
>>
>>Your second option would work of course. It does achieve the IOC aspect,
>>but doesn't remove the Spring (if the GenericFactory interface comes
>>from Spring), and you would have to cast in the using bean instead of in
>>the proxy. The IOC and hiding of other beans in the BF are probably the
>>most important things anyway.
>>
>>(Of course, both of these do have a negative aspect, compared to just
>>using BeanFactory directly; with BeanFActory the using bean can declare
>>itself BeanFactoryAware and get the reference with no extra
>>
>>
>configuration).
>
>
>>roger holbrook wrote:
>>
>>
>>
>>>Hi Colin
>>>
>>>Your thoughts on implementation hiding have got me thinking...
>>>
>>>But before I test anything could you clarify the sort of usage you
>>>have in mind - specifically, would it make a difference whether the
>>>implementation hiding factories were themselves 'typed' or 'generic' ie.
>>>
>>>
>do
>
>
>>>you want / need the type of the factory to vary with the type that it
>>>generates, or would a single generic factory be adequate ?
>>>
>>>In other words, does one or other of the following make a difference ?
>>>
>>>1. Typed interface factories:
>>>
>>>interface MyFirstInterfaceFactory {
>>> MyFirstInterface getInstance()
>>>}
>>>
>>>interface MySecondInterfaceFactory {
>>> MySecondInterface getInstance()
>>>}
>>>
>>>
>>>2. Generic interface factory:
>>>
>>>interface GenericFactory {
>>> Object getInstance()
>>> Class getClass()
>>>}
>>>
>>>where different instances of GenericFactory will return from getClass()
>>>
>>>
>the
>
>
>>>relevant type, MyFirstInterface, MySecondInterface etc..
>>>
>>>I'll try & test something tomorrow
>>>
>>>Roger
>>>
>>>
>>>
>>>"Colin Sampaleanu" <col...@ex...> wrote in message
>>>news:3FB...@ex......
>>>
>>>
>>>
>>>
>>>>I think I may be missing something, but I think it's desireable to be
>>>>able to create in an easy fashion, 'closures' which encapsulate getting
>>>>a bean from a bean factory.
>>>>
>>>>Say you have an interface
>>>> interface MyInteface { ... whatever }
>>>>
>>>>and you have a factory Interface
>>>> interface MyInterfaceFactory {
>>>> MyInterface getInstance();
>>>> }
>>>>
>>>>And you have a user of the factory, who you'd rather have no knowledge
>>>>of Spring, which is why he's using the factory instead of calling
>>>>getBean himself:
>>>>class User {
>>>> MyInterfaceFactory _myfac;
>>>> public void setMyInterfaceFactory(MyInterfaceFactory myfac) { _myfac =
>>>>myfac; }
>>>> public void someMethod() {
>>>> // need a new instance of MyInterface to work with
>>>> MyInterface myint = _myfac.getInstance();
>>>> ...
>>>> }
>>>>}
>>>>
>>>>Now I have a bean factory
>>>><beans>
>>>> <bean id="myinterface" singleton="false"
>>>>class="com.whatever.MyInterfaceImpl">
>>>> </bean>
>>>> <bean id="user" class="com.whatever.User">
>>>> <property name="myInterfaceFactory"><ref
>>>>
>>>>
>bean="xxxxxxxx"/></property>
>
>
>>>> </bean>
>>>></beans>
>>>>
>>>>now, as per the above, context.getBean("myinterface") is already a
>>>>factory for objects implementing MyInterface. But I don't want the User
>>>>object to know anything about contexts. And I'd rather not create an
>>>>actual object that implements MyInterfaceFactory. It seems like a waste,
>>>>since all I am doing here is trying to create a level of indirection,
>>>>and I already have a factory inside the context itself, and I may want
>>>>to use this approach in 30 different places, just to add a level of
>>>>indirection in creating new objects.
>>>>
>>>>So what I think is needed is some variation of ProxyFactoryBean (but a
>>>>separate class), which given a target bean (which is itself a factory),
>>>>and a factory interface having a method with no args which returns a
>>>>certain type, creates on the fly a new class implementing the factory
>>>>interface, which will just use the target factory bean to actually
>>>>supply the instance. So the bean def above would become:
>>>><beans>
>>>> <bean id="myinterface" singleton="false"
>>>>class="com.whatever.MyInterfaceImpl">
>>>> </bean>
>>>> <bean id="myinterface-factory"
>>>>
>>>>
>>>>
>>>>
>>>class="org.springframework.whatever.XXXX">
>>>
>>>
>>>
>>>
>>>> <property name="targetBean"><ref bean="xxxxxxxx"/></property>
>>>> <property
>>>>name="interface"><value>x.y.z.AFactoryInterface</value></property>
>>>> </bean>
>>>> <bean id="user" class="com.whatever.User">
>>>> <property name="myInterfaceFactory"><ref
>>>>bean="myinterface-factory"/></property>
>>>> </bean>
>>>></beans>
>>>>
>>>>Am I missing an existing way to do this? Is this worth adding to spring
>>>>as a convenience built-in, along the lines of
>>>>
>>>>
>TransactionProxyFactoryBean?
>
>
>>>>
>>>>
>>>>
>>
>>
|