title: Clean code - Where should @Autowired be applied?
body: <p>I'll start with a simple example. You have a Spring boot application that runs a <code>CommandLineRunner</code> class on initialization.</p>
  
  <pre><code>// MyCommandLineRunner.java
  public class MyCommandLineRunner implements CommandLineRunner {
      private final Log logger = LogFactory.getLog(getClass());
      @Autowired //IntelliJ Warning
      private DataSource ds;
      @Override
      public void run(String... args) throws Exception {
          logger.info("DataSource: " + ds.toString());
      }
  }
  // Application.java
  @SpringBootApplication
  public class Application {
      public static void main(String... args) {
          SpringApplication.run(Application.class, args); 
      }
      @Bean
      public MyCommandLineRunner schedulerRunner() {
          return new MyCommandLineRunner();
      }
  }
  </code></pre>
  
  <p>Now, like this, this works, everything is OK. However, IntelliJ reports a warning where <code>@Autowired</code> is located (I marked where in the comment)</p>
  
  <blockquote>
    <p><strong>Spring team recommends:</strong> Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies.</p>
  </blockquote>
  
  <p>Now if I follow this, I have a constructor based dependency injection</p>
  
  <pre><code>@Autowired
  public MyCommandLineRunner(DataSource ds) { ... }
  </code></pre>
  
  <p>This also means that I have to edit <code>Application.java</code> as well, since the constructor needs an argument. In <code>Application.java</code> if I try to use the setter injection, I'll get the same warning. If I refactor that as well, I'll end up with some, in my opinion, nasty code.</p>
  
  <pre><code>// MyCommandLineRunner.java
  public class MyCommandLineRunner implements CommandLineRunner {
      private final Log logger = LogFactory.getLog(getClass());
      private DataSource ds;
      @Autowired // Note that this line is practically useless now, since we're getting this value as a parameter from Application.java anyway.
      public MyCommandLineRunner(DataSource ds) { this.ds = ds; }
      @Override
      public void run(String... args) throws Exception {
          logger.info("DataSource: " + ds.toString());
      }
  }
  // Application.java
  @SpringBootApplication
  public class Application {
      private DataSource ds;
      @Autowired
      public Application(DataSource ds) { this.ds = ds; }
      public static void main(String... args) {
          SpringApplication.run(Application.class, args); 
      }
      @Bean
      public MyCommandLineRunner schedulerRunner() {
          return new MyCommandLineRunner(ds);
      }
  }
  </code></pre>
  
  <p>The above code yields the same result, but doesn't report any warnings in IntelliJ.
  I'm confused, how is the 2nd code better than the first one? Am I following an incorrect logic? Should this be wired differently?</p>
  
  <p><strong>In short, what's the correct way to do this?</strong></p>
  
  <p><em>note</em> <code>DataSource</code> is just a pure example, this question applies to anything being autowired.</p>
  
  <p><em>note 2</em> Just to say that <code>MyCommandLineRunner.java</code> can't have another, empty, constructor, since DataSource needs to be autowired/initialized. It will report an error and will not be compiled.</p>