java - Spring Autowire Annotation with Several Interface Implementations -
suppose have 1 interface
public interface { public void dosomething(); }
and 2 implementation classes
@component(value="aimpl1") public class aimpl1 implements { } @component(value="aimpl2") public class aimpl2 implements a{ }
and class use "a" implementation:
@component public class myclass { @autowire a; }
now if want inject aimpl1 add @qualifier("aimpl1") while if want inject aimpl2 add @qualifier("aimpl2")
the question is: possible instruct spring somehow implementations of "a" in case aimpl1 , aimpl2 , use application specific conventions choose appropriate implementation? example in case convention use implementation greatest suffix (i.e. aimpl2)?
edit: class myclass should not aware @ implementation lookup logic, should find property "a" set object of aimpl2.
assuming have hundreds of interfaces , implementations (as said in comment), , not want refactor code... tricky problem... , tricky solution:
you create custom beandefinitionregistrypostprocessor
, implement either method postprocessbeandefinitionregistry
or postprocessbeanfactory
.
this way have access all bean definitions before instantiated , injected. logic find preferred implementation each 1 of interfaces, , then, set 1 primary.
@component public class custombeandefinitionregistrypostprocessor implements beandefinitionregistrypostprocessor { @override public void postprocessbeandefinitionregistry( beandefinitionregistry registry) throws beansexception { // method can used set primary bean, although // beans defined in @configuration class not avalable here. } @override public void postprocessbeanfactory( configurablelistablebeanfactory beanfactory) throws beansexception { // here, beans available including defined @configuration, @component, xml, etc. // magic somehow find preferred bean name each interface // have access bean-definition names with: beanfactory.getbeandefinitionnames() string beanname = "aimpl2"; // let's 1 // definition bean , set primary beanfactory.getbeandefinition(beanname).setprimary(true) } }
the hard part find bean name, depends of specifics of application. guess having consistent naming convention help.
update:
it seems both methods in interface beandefinitionregistrypostprocessor
can used purpose. having in mind in postprocessbeandefinitionregistry
phase, beans configured through @configuration classes not yet available, noted in comments below.
on other hand indeed available in postprocessbeanfactory
.
Comments
Post a Comment