Clean code - Where should @Autowired be applied?

前端 未结 2 2132
北海茫月
北海茫月 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:37

    Consider making the field ds final, then you don't need @Autowired. See more about dependency injection http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-spring-beans-and-dependency-injection.html#using-boot-spring-beans-and-dependency-injection

    To keep the code clean, have you considered using Lombok annotations? @RequiredArgsConstructor(onConstructor = @__(@Autowired)) would generate the constructor with @Autowired annotations. See more here https://projectlombok.org/features/Constructor.html

    Your code could look like this:

    @Slf4j
    @RequiredArgsConstructor
    // MyCommandLineRunner.java
    public class MyCommandLineRunner implements CommandLineRunner {
    
        //final fields are included in the constructor generated by Lombok
        private final DataSource ds;
    
        @Override
        public void run(String... args) throws Exception {
            log.info("DataSource: {} ", ds.toString());
        }
    }
    
    // Application.java
    @SpringBootApplication
    @RequiredArgsConstructor(onConstructor_={@Autowired}) // from JDK 8
    // @RequiredArgsConstructor(onConstructor = @__(@Autowired)) // up to JDK 7
    public class Application {
    
        private final Datasource ds;
    
        public static void main(String... args) {
            SpringApplication.run(Application.class, args);
        }
    
        @Bean 
        public MyCommandLineRunner schedulerRunner() {
            return new MyCommandLineRunner(ds);
        }
    }
    

    Later edit

    Solution without Lombok relies on Spring to inject dependency when the bean is created

    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
        @Bean
        /**
         * dependency ds is injected by Spring
         */
        public MyCommandLineRunner schedulerRunner(DataSource ds) {
            return new MyCommandLineRunner(ds);
        }
    }
    
    // MyCommandLineRunner.java
    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());
        }
    }
    

提交回复
热议问题