Spring: Injecting a private inner class as an outer class's member?
I have the following class structure
public class Outer{
private Mapper a;
....
private class MapperA implements Mapper {
}
private class MapperB implements Mapper {
}
}
In my Spring config file I would like to create a an Outer bean, and assign one of MapperA or MapperB as a property. Is this possible?
<bean id="outer" class="mypackage.Outer">
<property name="a" ?????='????' />
</bean>
Edit: Some more info, based on the feedback from answers:
I got lazy with my above example. I do have a public setter/getter for the Mapper instance variable.
开发者_C百科The reason all of the Mapper classes are inner classes is because there could potentially be many of them, and they will only ever be used in this class. I just don't want a ton of cruft classes in my project. Maybe a factory method is a better idea.
Spring can instantiate private
inner classes. The actual problem with your config is that they are also non-static
, so you need a <constructor-arg .../>
:
<bean id="outer" class="mypackage.Outer">
<property name = "a">
<bean class = "mypackage.Outer.MapperA">
<constructor-arg ref = "outer" />
</bean>
</property>
</bean>
Normally you'd need a setter for the Mapper
within Outer
, and an instance of the required Mapper
. But as these are:
- private
- inner
classes, that becomes a bit tricky (as you've identified). If you make them public, I'm sure you could creae an instance using Outer$MapperA
etc. But that seems a little nasty. So:
- do they need to be inner and private ?
- perhaps Outer can take a String, and determine from that whether to instantiate
MapperA
orMapperB
. i.e. there's some factory capability here.
The simplest thing to do is to really determine if they need to be inner/private. If so, then they really shouldn't be referenced within the config, which should be talking about publicly accessible classes.
As far as I know, it's impossible until you make MapperA
and MapperB
usual public classes.
But if you do want to keep them as inner private classes then you can "inject" them manually.
You'll need to create method with @PostInit
annotation and initialize your a
field there (a = new MapperA ()
for example, or something more complex). With this approach you should also check that initialization callbacks are switched-on in your spring configuration.
精彩评论