简体   繁体   中英

How does spring boot inject the instance of ApplicationContext and JdbcTemplate using @Autowired without @Component annotation and xml configuration?

i'm in a spring boot app building rest controller.i find that ApplicationContext and JdbcTemplate source code,these 2 classes do not have any annotation.But they can be correctly injected into constructor.i am not using any configuration file like 'applicationContext.xml'.When do these 2 classes get scanned by spring ioc container?

update:i split @SpringBootApplication into @Configuration,@EnableAutoConfiguration,@ComponentScan.And then remove @EnableAutoConfiguration,the injection still works,why?

@SpringBootApplication
@RestController
@CrossOrigin
@Validated
@RequestMapping(value = "/demo")
public class DemoController {
private ApplicationContext applicationContext;
private JdbcTemplate jdbcTemplate;
@Autowired
public DemoController(ApplicationContext applicationContext, JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        this.applicationContext = applicationContext;
}}

Spring Boot does a lot of auto configuration.

I assume that you are using spring-data-jdbc or spring-data-jpa and there for the JdbcTemplate is auto configured.

ApplicationContext will be around anyway because this is the bean factory class to access beans programatically.

You can checkout the source code here: https://github.com/spring-projects/spring-boot

The most interesting project is: spring-boot-autoconfigure where all the magic happens.

And there you will find JdbcTemplateConfiguration.java

@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(JdbcOperations.class)
class JdbcTemplateConfiguration {

    @Bean
    @Primary
    JdbcTemplate jdbcTemplate(DataSource dataSource, JdbcProperties properties) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        JdbcProperties.Template template = properties.getTemplate();
        jdbcTemplate.setFetchSize(template.getFetchSize());
        jdbcTemplate.setMaxRows(template.getMaxRows());
        if (template.getQueryTimeout() != null) {
            jdbcTemplate.setQueryTimeout((int) template.getQueryTimeout().getSeconds());
        }
        return jdbcTemplate;
    }

}

Here main Spring boot goals

  • Avoid complex XML configuration in Spring
  • Develop a production ready Spring applications in an easier way
  • reduce the development time and run the application independently
  • Offer an easier way of getting started with the application

Spring boot via the concept of starter dependencies works in configuration by exception .

It automatically configures your Spring application based on the JAR dependencies you added in the project.

Exemple with starter-jdbc you can inject automatically the JdbcTemplate without any xml configuration.

with the starter-test you got automatically in your classpath these libraries Spring Test, JUnit, Hamcrest, and Mockito

with the starter-mail you have an out-of-the-box JavaMail bean that you can inject in your services...

And so on....

All this magic comes with this annotation @EnableAutoConfiguration

This annotation will trigger the auto-configuration of the Spring Application Context, attempting to guess and configure beans that you are likely to need. Auto-configuration classes are usually applied based on your classpath.

When using @SpringBootApplication, the auto-configuration of the context is automatically enabled and adding this annotation has therefore no additional effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM