简体   繁体   中英

Spring @Autowire with Inheritance

I am new to Spring and wanted your all assistance. I have run into the "expected single match bean but found two" exception. I have searched for the solution and think have understood the solution. Most solutions suggest using @Qualifier to resolve this exception. However I don't think it will solve my issue. Below is my class hierarchy:

abstract class A{

    @Autowired
    Client client;                     

    protected void doSomething(){ 
        /* ....some code .... */
        client.someStuff(); 
        /* ....some code .... */
    }

    /* ..... few abstract methods ......... */
}

class B extends A{ 
    public void action(){ doSomething() }
}

class C extends A{
    public void action(){ doSomething() }
}

My .xml confirugration file is

    <bean id="authClientA"  class="com.xyz.Client">
        <property name="auth" value="abc">
    </bean>


    <bean id="authClientB"  class="com.xyz.Client">
        <property name="auth" value="xyz">
    </bean>

    <bean id="beanA"  class="ClassA">
        <property name="client"  ref="authClientA">
    </bean>

    <bean id="beanB"  class="ClassB">
        <property name="auth" ref="authClientB">
    </bean>

So basically, I have an abstract class which has a method which will be common to both the subclasses. This method uses the client reference but at run time will use different object. doSomething() is not overridden in the subclasses.

So when I try to run this code, it gives me the exception for client reference. I dont think I can use @Qualifier because @Qualifier requires to specify bean name from .xml as parameter, but since the 'client' attribute is common, I cant use only one bean name.

Can someone please assist in explaining if there is a way to get around. Duplicating the doSomething() method defeats the entire purpose of inheritance and will cause duplicate code across classes. I can't have the client attribute in the subclasses as it will become unknown to doSomething() method at compile time.

Any ideas/suggestions/solutions will be helpful.

Thanks in advance :)

@Qualifier is the option, you are probably not able to use it.

Modifying your XML:

<bean id="authClientA"  class="com.xyz.Client">
    <property name="auth" value="abc">
    <qualifier value="clientA" />
</bean>


<bean id="authClientB"  class="com.xyz.Client">
    <property name="auth" value="xyz">
    <qualifier value="clientB" />
</bean>

<bean id="beanA"  class="ClassA">
    <property name="client"  ref="authClientA">
</bean>

<bean id="beanB"  class="ClassB">
    <property name="auth" ref="authClientB">
</bean>

And fixing your class:

abstract class A{

      @Qualifier("clientA")
      Client clientA;                     

      @Qualifier("clientB")
      Client clientB;       

      protected void doSomething(){ 
               /* ....some code .... */
               client.someStuff(); /* HERE YOU NEED SOME LOGIC TO INVOKCE THE CORRECT OBJECT METHOD */
               /* ....some code .... */
      }

      /* ..... few abstract methods * ........./
}

Also, if you want to understand more, please check this answer here :

Spring Autowire Annotation on Abstract class: No unique bean is defined

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM