10

I have a bean:

    <bean id="BasketLogic" class="efco.logic.EfcoBasketLogic" autowire="byType">
        <property name="documentLogic" ref="DocumentLogic" />
        <property name="stateAccess" ref="StateAccess" />
        <property name="contextAccess" ref="ContextAccess" />
    </bean>

  <bean id="EfcoErpService" autowire="byType" class="efco.erp.service.EfcoErpServiceImpl">
    <constructor-arg ref="ErpConnector"/>
  </bean>

documentLogic, stateAccess and contextAccess are fields on BasketLogicImpl

And I do not have <context:component-scan />

EfcoBasketLogic.java:

public class EfcoBasketLogic extends BasketLogicImpl {

        @Inject
        private EfcoErpService erpService;
    ...
    ...
    ...
}

erpService is null, unless I provide a setter. But why? I thought a setter isn't needed where autowiring is taking place? Could it be that BasketLogicImpl is responsible for that?

GarfieldKlon
  • 11,170
  • 7
  • 31
  • 33

3 Answers3

11

You need to use a setter because annotations are not detected unless spring is told so through either <context:component-scan /> or <context:annotation-config />. Setter is detected because you specified autowire="byType".

You may find this question and answer helpful as well: When to use autowiring in Spring

Community
  • 1
  • 1
mrembisz
  • 12,722
  • 7
  • 36
  • 32
  • If I do so a new problem appears --> _No unique bean of type [xyz] is defined: expected single matching bean but found 5_. That's caused by an other bean where I explicitly inject a property via `` and there are 5 beans which implements that interface. Property 'x' has the annotation @Inject. So it seems like explicit defining does not override the autowired stuff? – GarfieldKlon Nov 02 '12 at 11:37
  • `@Inject` will be resolved properly if there is just one bean of given type or one marked as primary. If you have multiple interchangeable beans of that type you need to inject by name using `@Resource` or xml. – mrembisz Nov 02 '12 at 12:35
  • Even if I explicitly inject that bean via `` ? – GarfieldKlon Nov 02 '12 at 12:57
  • I recommend asking another question. I have answered your original question and cannot really get what's your next problem without more detailed description including some code or xml. – mrembisz Nov 02 '12 at 13:13
  • My question was why I have to write a setter (when I'm not using component-scan or annotation-config). – GarfieldKlon Nov 02 '12 at 13:37
  • Ok, but why do I have to write a setter if I'm using autowire="byType" and annotated the field with @Inject? Is that intended, the way to go? I mean I can throw away the setter if I would use annotation-config. So there is a difference between it and autowire="byType"? – GarfieldKlon Nov 02 '12 at 14:52
  • Autowiring detects setters and constructor parameters as potential dependencies. Not private fields. Annotations are invisible unless you demand they are checked for. – mrembisz Nov 02 '12 at 17:22
1

First of all, the use of <context:component-scan /> or <context:annotation-config /> enables Spring to scan your code for eligible beans to meet dependencies, which will greatly improve it's ability to wire them up correctly, so I suggest adding them to your context file.

Second, you should be aware that @Inject is a standard (meaning JSR-330 specification) annotation. It is okay to mix and match Spring annotations with standard ones, but behavior may vary when doing so. @Named is commonly paired with @Inject to match components with dependencies (both JSR-330). See this reference for details, and refer to Table 4.6 for usage comments.

But to directly answer your question, "why do I need a setter when not using component-scan", is because you are not using component-scan. You are asking Spring to inject a dependency "byType", but not allowing Spring to scan your code for components which are of that type. The reason the setter works is that the type of the setter argument being injected can be discovered by Spring in the compiled bytecode (i.e. meta-data), and so it successfully resolves your request.

pmhargis
  • 713
  • 6
  • 7
  • FYI: When using ` `, make sure you set the base-package attribute at the root of your class hierarchy where bean classes are declared (via @Named or @Autowired). For example: – pmhargis Sep 03 '13 at 19:18
0

My understanding is that XML configuration overrides annotation config.The fact that autowire="byType" specified overrides the auto injection, which looks for a presence of setter method for injecting the dependency.

kbk
  • 81
  • 3