25

Why does this work:

@Configuration
public class MyConfig {

  @Bean
  public A getA() {
    return new A();
  }

  @Bean               // <-- Shouldn't I need @Autowired here?
  public B getB(A a) {
    return new B(a);
  }  
}

Thanks!

Eric Palakovich Carr
  • 22,701
  • 8
  • 49
  • 54
Jan Żankowski
  • 8,690
  • 7
  • 38
  • 52

3 Answers3

26

@Autowire lets you inject beans from context to "outside world" where outside world is your application. Since with @Configuration classes you are within "context world ", there is no need to explicitly autowire (lookup bean from context).

Think of analogy like when accessing method from a given instance. While you are within the instance scope there is no need to write this to access instance method, but outside world would have to use instance reference.

Edit

When you write @Configuration class, you are specifying meta data for beans which will be created by IOC.

@Autowire annotation on the other hand lets you inject initialized beans, not meta-data, in application. So, there is no need for explicit injection because you are not working with Beans when inside Configuration class.

John
  • 5,189
  • 2
  • 38
  • 62
  • 3
    Thanks! Is this written somewhere in the Spring docs? Where the boundary between "outside" and "context" worlds lies? :) – Jan Żankowski Aug 19 '15 at 12:13
  • That is a good question and i am not sure if there is explicit documentation about this. The boundary would be @Configuration (which makes class marked as one containing beans definitions for IOC). Hopefully i am not mistaken, but you shouldn't be able to omit autowire in anything which is not Configuration. – John Aug 19 '15 at 12:19
  • From the Javadoc of Configuration: "@ Configuration is meta-annotated with @ Component, therefore @ Configuration classes are candidates for component scanning ([...]) and therefore may also take advantage of @ Autowired/@ Inject at the field and method level (but not at the constructor level)." To me, this actually seems to indicate that I *need* to use @ Autowired on @ Bean methods... Unless @ Bean methods are somehow doubly-special and excluded from the above prescription. Ah, the magic of Spring. :) – Jan Żankowski Aug 21 '15 at 17:07
  • 1
    Got it :) You need autowire if you inject between different configuration classes: http://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch04s02.html but not internally - scroll previos to chapters to 2.2 . This makes sense because when one @Configuration class is scaned and meta data processed, there are initialized beans in IOC. – John Aug 21 '15 at 18:00
11

Hi Jan your question is marked as answered over 4 years ago but I've found a better source: https://www.logicbig.com/tutorials/spring-framework/spring-core/javaconfig-methods-inter-dependency.html

here's another article with the same idea: https://dzone.com/articles/spring-configuration-and, it also states that such usage is not well documented which I found true. (?)

so basically if beanA's initialization depends on beanB, spring will wire them without explicit @Autowired annotation as long as you declare these two beans in the application context (i.e. @Configuartion class).

enter image description here

mzoz
  • 1,273
  • 1
  • 14
  • 28
-1

A class with @Configuration annotation is where you're defining your beans for the context. But a spring bean should define its own dependencies. Four your case B class should be defining it's own dependencies in class definition. For example if your B class depends on your A class than it should be like below:

public class B
{
    @Autowired
    A aInstance;

    public A getA()
    {
        return aInstance;
    }

    public void setA(A a)
    {
        this.aInstance =  a;
    }
}

In above case while spring is building its context it looks for the bean which's type is A which is also defined as a Bean at your configuration class and Autowires it to B at runtime so that B can use it when required.

FDirlikli
  • 185
  • 1
  • 4
  • Hmm .. I'm afraid this doesn't seem to answer my question. I'm asking why the code I pasted above works without @ Autowired, not how B should be written. I'm just curious how @ Autowired works, exactly. The docs don't seem to explain it in its entirety. – Jan Żankowski Aug 19 '15 at 12:06