|
From: Colin S. <col...@ex...> - 2003-11-14 22:55:27
|
There is definitely an issue. When trying to use the two argument
constructor, of which there is only one, I get
; nested exception is:
org.springframework.beans.factory.BeanDefinitionStoreException: 2
constructor arguments specified but just constructor with 1 arguments
found in bean 'packaging-context'
org.springframework.beans.factory.BeanDefinitionStoreException: 2
constructor arguments specified but just constructor with 1 arguments
found in bean 'packaging-context'
at
org.springframework.beans.factory.support.AbstractBeanFactory.autowireConstructor(AbstractBeanFactory.java:444)
at
org.springframework.beans.factory.support.AbstractBeanFactory.createBean(AbstractBeanFactory.java:352)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getSharedInstance(AbstractBeanFactory.java:274)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:203)
at
org.springframework.beans.factory.support.AbstractBeanFactory.resolveReference(AbstractBeanFactory.java:717)
at
org.springframework.beans.factory.support.AbstractBeanFactory.resolveValueIfNecessary(AbstractBeanFactory.java:688)
at
org.springframework.beans.factory.support.AbstractBeanFactory.autowireConstructor(AbstractBeanFactory.java:418)
at
org.springframework.beans.factory.support.AbstractBeanFactory.createBean(AbstractBeanFactory.java:352)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getSharedInstance(AbstractBeanFactory.java:274)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:203)
at
org.springframework.beans.factory.support.AbstractBeanFactory.resolveReference(AbstractBeanFactory.java:717)
at
org.springframework.beans.factory.support.AbstractBeanFactory.resolveValueIfNecessary(AbstractBeanFactory.java:688)
at
org.springframework.beans.factory.support.AbstractBeanFactory.autowireConstructor(AbstractBeanFactory.java:418)
at
org.springframework.beans.factory.support.AbstractBeanFactory.createBean(AbstractBeanFactory.java:352)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getSharedInstance(AbstractBeanFactory.java:274)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:203)
at
org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:468)
at
org.springframework.context.support.AbstractApplicationContext.preInstantiateSingletons(AbstractApplicationContext.java:354)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:240)
However, if I add index="0" and index="1" respectively, to the two
constructor arguments, then it has no problem constructing it. Now my
understanding is that the indexes shouldn't be necessary in this
(non-ambiguous) case.
Again, I'll probably be able to look at this on Mon. or Tues. if nobody
else has by then.
Regards,
Colin
Colin Sampaleanu wrote:
> Juergen,
>
> I think the constructor resolution may not be quite right. The
> following bean entry fails:
> <bean id="data-access-context"
>
> class="org.springframework.context.support.ClassPathXmlApplicationContext">
>
> <constructor-arg>
> <list><value>/data-access-applicationContext.xml</value></list>
> </constructor-arg>
> </bean>
> with
> ...
>
> org.springframework.beans.factory.UnsatisfiedDependencyException: Bean w
> ith name 'data-access-context' has an unsatisfied dependency expressed
> through c
> onstructor argument with index 0 of type [java.lang.String]
>
> Where it should be able to resolve to the constructor which takes an
> array of Strings. Now I will probably look into this myself later, but
> wanted to give you a heads up in case you know offhand what the
> problem is. For the time being, I am in a hurry, and will just feed
> the one string I need to the constructor which takes one string.
>
> As to why I am trying to construct a context inside a context, I am
> doing some interesting coding; we can get into that later when
> everything is working :-)
>
>
>
>
> jürgen höller [werk3AT] wrote:
>
>> Due to popular demand ;-), I've just added a constructor detection
>> algorithm that replaces the former single-constructor requirement. It
>> works similar to Pico's constructor resolution: It starts with the
>> "greediest" constructor, i.e. the one with the most arguments, and
>> then falls back to the next one in the greediness order if it can't
>> resolve all dependencies. If there are multiple constructors with the
>> same number of arguments, all of them are tried; the first one that
>> can be satisfied will be used.
>>
>> Of course, all "constructor-arg" hints will be applied in any case;
>> autowire="constructor" will just resolve all remaining arguments. A
>> few sanity checks are performed, like only resolving a constructor
>> that has at least as many arguments as there are "constructor-arg" tags.
>>
>> This should be sufficiently powerful to be able to address *any*
>> constructor. For example, if there are constructors
>> (DataSource,TestBean) and (TestBean,DataSource), autowiring or
>> generic "constructor-arg" tags with a DataSource and a TestBean will
>> use an undetermined one of the two (generally, the first one
>> according to the order of Class.getConstructors, which can vary from
>> JVM to JVM). If you need a specific one, use "constructor-arg" with
>> corresponding "index" attributes.
>>
>> If multiple constructors with the same number and position of
>> arguments match, like (DataSource,TestBean) and (DataSource,Object),
>> a type difference weight algorithm will kick in. It will determine a
>> weight for the difference between the argument types and the actual
>> arguments, prefering more exact matches - (DataSource,TestBean) in
>> case of DataSource and TestBean args, in the above case.
>>
>> BTW, Rob, Pico still advocates the single constructor paradigm. Their
>> introduction (http://www.picocontainer.org/introduction.html) still
>> states that Pico components need to have one single constructor,
>> while their FAQ talk about resolving an appropriate constructor
>> (http://www.picocontainer.org/faq.html#many-constructors) - so much
>> for documentation consistency.
>>
>> I consider our Type 3 IoC support now more capable than Pico's: We
>> also support arrays, lists, and maps of components or parameters
>> going into constructor arguments, just like we do with bean
>> properties. Effectively, bean-style Type 2 IoC vs constructor-style
>> Type 3 IoC is now the application developer's choice when using a
>> Spring bean factory. Note that the Pico guys have already stated that
>> they will *not* support Type 2 IoC any time soon but just their
>> flavour of Type 3.
>>
>> Juergen
>>
>>
>> -----Original Message-----
>> From: spr...@li...
>> [mailto:spr...@li...]On Behalf
>> Of Rob Butler
>> Sent: Sunday, November 09, 2003 11:47 PM
>> To: spr...@li...
>> Subject: [[W3-SPAM]] - Re: [Springframework-developer] Type 3 IoC
>> support - Email found in subject
>>
>>
>> I would agree this is very good stuff! This is especially useful if you
>> want to use a third party api but they do not conform to javabean style
>> no-arg contructors. However by limiting the implementation to only
>> support
>> classes that have a single constructor you are all but defeating its
>> usefulness.
>>
>> The only reason you would be forced to use / need this kind of a
>> feature is
>> if you don't have access to the code to implement a no-arg
>> constructor. For
>> that same reason, you cannot modify the code to only have 1
>> constructor. I
>> would wager that most classes that do provide a constructor which
>> takes args
>> also supply variations that take more / less args. So if multiple
>> constructors are not supported, it's probably not going to be very
>> useful.
>>
>> Spring is already amazing, and you guys just keep making it better.
>> Good
>> work!
>>
>> Later
>> Rob
>>
>>
>>>> The only limitation is that constructor-wired components are just
>>>> allowed
>>>>
>>>
>> to have one single constructor. This is also what Pico recommends,
>> although
>> they have some heuristic kind of constructor choice in case of multiple
>> constructors now. I guess we can limit this to one single constructor
>> for
>> the time being. Of course, standard beans defined without
>> autowire="constructor" or "constructor-arg" tags can still have any
>> number
>> of constructors, the only requirement being that they must provide a
>> no-arg
>> constructor.
>>
>>
>>>>
>>>
>>> One way you could do it (which you probably thought of) is by allowing
>>> the deployer to specify, in the case of the indexed variant, an
>>> optional
>>> 'type' attribute which specifies the real type (in the receiving
>>> object)
>>> of that constructor argument. This would allow the appropriate
>>> constructor to be picked without any ambiguity. I don't know if this is
>>> worth doing or not, but on the other hand, if you are going to support
>>> constructors at all, it's somewhat arbitrary to stop at 1 if you can
>>> figure out a relatively simple (albeit wordy) way to support the
>>> multiple case.
>>>
>>> Even if that is not done, maybe it is worth it supporting the special
>>> case of classes which have a no-arg constructor, and one other
>>> constructor with one or more args. That's also a pretty common case,
>>> and
>>> easy to support.
>>>
>>> Regards,
>>> Colin
>>>
>>
|