Results 1 to 5 of 5

Thread: Autowiring fails at root context

  1. #1
    Join Date
    Sep 2005
    Location
    Webster Groves, MO
    Posts
    95

    Question Autowiring fails at root context

    I created a new Spring MVC project using the Spring Template Project functionality. Since 2.3 or so, the format of the configuration files has changed a bit, so that there's now this root-context.xml file created. I get the idea, you can create stuff at the root level, then any Spring servlet context that's created later essentially inherits that root context.

    The problem is that auto-wiring at that root level doesn't appear to work properly. Here's a sample project I've created that illustrates the problem:

    SpringMvcSandbox.zip

    Both root-context.xml (at the root level) and servlet-context.xml (at the servlet level) have an import statement like this:

    HTML Code:
    <import resource="../services/service-context.xml"/>
    For the root, the import path is different, but otherwise it's the same. If you comment out the import at the root level, UNCOMMENT the import at the servlet level, and run the app, everything works: the DateService gets wired into the HomeService and HomeController will display a message.

    Now reverse that: UNCOMMENT the import at the ROOT level, COMMENT the import at the SERVLET level, and run it. You'll get a NPE where the HomeService tries to reference the DateService. You can make it work by uncommenting the direct property reference in the service-context.xml (which is commented out in my sample code), so it's not that you can't cross-reference beans in the root context, just that that never gets autowired.

    This may be by design, may be known, or whatever, but I just spent a while totally confused as to why my really simple autowire references weren't working! Is this because the root context isn't actually instantiated until referenced by a child or... I just don't know why the autowire isn't performed. Any ideas?
    Rick Herrick

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    You use @Autowired but in the root context you have nothing which knows what to do with that annotation... Basically putting an annotation somewhere and nothing registering something that knows what to do is pretty much useless. Like putting an @Transactional and not a tx:annotation-driven. For @Autowired to work you either need a context:annotation-config or enable component-scanning (which implies annotation-config and which is enabled in your servlet).

    Next to that you shouldn't import the service.xml in both context as that would give you two instances of the beans.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Sep 2005
    Location
    Webster Groves, MO
    Posts
    95

    Default

    Hey Marten,

    I meant to say thanks for this explanation earlier, but... well, I'll say thanks for this explanation later

    Regarding importing service.xml, I have it in both areas just for illustration in the sample code. One of them needs to be commented out or you'll get an exception due to the bean naming duplication.

    My understanding was that the @Autowired would get resolved when the beans are all fully loaded into the application context. The beans can be loaded either automatically through a scan (e.g. <mvc:annotation-driven>) or by explicit definition in a <bean> tag. So I guess you're saying that auto-wiring ONLY works with the scan process and only beans created through scanning will ever get auto-wired, right?
    Rick Herrick

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    No that isn't what I'm saying...

    If you use @Autowired you need something in the ApplicationContext that knows what to do with that annotation which is the AutowiredAnnotationBeanPostProcessor. You either
    1) Declare the AutowiredAnnotationBeanPostProcessor as a bean yourself
    2) specify context:annotation-driven which registers the AutowiredAnnotationBeanPostProcessor for you
    3) you specify context:component-scan, which basically also does 2

    You can perfectly well define your beans in xml but if you want to use @Autowired next to defining your beans you need to do either 1 or 2.

    Basically there is nothing preventing you from combining scanning, defining it in xml, properties files or java config you can mix and match as you like..
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5
    Join Date
    Sep 2005
    Location
    Webster Groves, MO
    Posts
    95

    Default

    Excellent, thanks for the info, Marten. It's the post-processing that I was missing. I just modified the non-scan load to add in the post-processor bean and the auto-wiring happened properly.
    Rick Herrick

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •