Clean code - Where should @Autowired be applied?

前端 未结 2 2136
北海茫月
北海茫月 2021-02-12 19:44

I\'ll start with a simple example. You have a Spring boot application that runs a CommandLineRunner class on initialization.

// MyCommandLineRunner.         


        
2条回答
  •  野的像风
    2021-02-12 20:19

    There are several ways to improve it.

    1. You can remove @Autowired from your MyCommandLineRunner as you are letting a @Bean method construct an instance of it. Inject the DataSource directly into the method as an argument.

    2. Or remove @Autowired and remove the @Bean and slap a @Component annotation on your MyCommandLineRunner to have it detected and remove factory method.

    3. Inline your MyCommandLineRunner inside your @Bean method as a lambda.

    No Autowiring in the MyCommandLineRunner

    public class MyCommandLineRunner implements CommandLineRunner {
        private final Log logger = LogFactory.getLog(getClass());
        private final DataSource ds;
    
        public MyCommandLineRunner(DataSource ds) { this.ds = ds; }
    
        @Override
        public void run(String... args) throws Exception {
            logger.info("DataSource: " + ds.toString());
        }
    }
    

    And the application class.

    @SpringBootApplication
    public class Application {
    
        public static void main(String... args) {
            SpringApplication.run(Application.class, args); 
        }
    
        @Bean
        public MyCommandLineRunner schedulerRunner(DataSource ds) {
            return new MyCommandLineRunner(ds);
        }
    }
    

    Usage of @Component

    @Component
    public class MyCommandLineRunner implements CommandLineRunner {
        private final Log logger = LogFactory.getLog(getClass());
        private final DataSource ds;
    
        public MyCommandLineRunner(DataSource ds) { this.ds = ds; }
    
        @Override
        public void run(String... args) throws Exception {
            logger.info("DataSource: " + ds.toString());
        }
    }
    

    And the application class.

    @SpringBootApplication
    public class Application {
    
        public static void main(String... args) {
            SpringApplication.run(Application.class, args); 
        }
    
    }
    

    Inline CommandLineRunner

    @SpringBootApplication
    public class Application {
    
        private static final Logger logger = LoggerFactory.getLogger(Application.class)
    
        public static void main(String... args) {
            SpringApplication.run(Application.class, args); 
        }
    
        @Bean
        public MyCommandLineRunner schedulerRunner(DataSource ds) {
            return (args) -> (logger.info("DataSource: {}", ds); 
        }
    }
    

    All of these are valid ways of constructing your instances. Which one to use, use the one that you feel comfortable with. There are more options (all variations on the ones mentioned here).

提交回复
热议问题