springboot -- When did application.properties and application.yml resolve

Keywords: Java Spring Mybatis SpringBoot xml

Preface

springboot must be familiar with it, one of its important features is automatic configuration (usually used to some settings configuration as the default configuration). springboot advocates the concept of no XML configuration files, and applications generated using springboot will not generate any configuration code and XML configuration files at all. Let's start with an example of spring boot integrating mybatis.
Step 1: Introduce the pom file

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

Step 2: Because I use the xml configuration file to use mybatis, add the following configuration to the application.properties file:

#Specify the location of the mapper file
mybatis.mapper-locations=classpath:mapper/*.xml

#Data Source Information
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/zplxjj?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

Step 3: Add entity classes, dao, mapper files

Step 4: Add annotations to the startup class

@SpringBootApplication
@MapperScan("com.stone.zplxjj.dao")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Step 5: So far, the configuration is complete, just write a one-sided, springboot has perfectly integrated mybatis

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
    @Autowired
    UserMapper userMapper;

    @Test
    public void testMybatis() {
        System.out.println(userMapper.selectByPrimaryKey(1L));
    }
}

@EnableAutoConfiguration

Through the example above, we find that integrating mybatis is very simple, the injection of those tedious classes is not written, only need to add some configuration of the database, which @Enable AutoConfiguration contributes. @ The Enable AutoConfiguration annotation is already in @SpringBoot Application

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    Class<?>[] exclude() default {};

    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    String[] excludeName() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};
}

We see the @Enable AutoConfiguration structure as follows:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

Import is an important annotation that works. This Spring provides an annotation that can be imported into the configuration class or beans into the current class. We go into the AutoConfiguration Import Selector class to see. The method is too long, intercepting the two core methods:

    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.filter(configurations, autoConfigurationMetadata);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }

By annotating the start of the project, you can see that Mybatis AutoConfiguration has been introduced.

Mybatis AutoConfiguration can be introduced by calling spring. factories specified in mybatis-spring-boot-autoconfigure-2.0.1.jar package to scan jar packages loaded with META-INF/spring.factories files to identify which classes are automatically configured.

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

@Conditional

@ The function of Conditional can load specific bean s according to the conditions. The principle is not discussed here. springboot implements several annotations based on this, which makes it easier to implement conditional loading classes.
@ Conditional OnBean: Is there a corresponding instance in the Spring container
@ Conditional OnMissing Bean: Is there a lack of corresponding instances in the Spring container
By looking at SqlSession Factory in Mybatis AutoConfiguration

    @Bean
    @ConditionalOnMissingBean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setVfs(SpringBootVFS.class);
        if (StringUtils.hasText(this.properties.getConfigLocation())) {
            factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
        }

        this.applyConfiguration(factory);
        if (this.properties.getConfigurationProperties() != null) {
            factory.setConfigurationProperties(this.properties.getConfigurationProperties());
        }

        if (!ObjectUtils.isEmpty(this.interceptors)) {
            factory.setPlugins(this.interceptors);
        }

        if (this.databaseIdProvider != null) {
            factory.setDatabaseIdProvider(this.databaseIdProvider);
        }

        if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
            factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
        }

        if (this.properties.getTypeAliasesSuperType() != null) {
            factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());
        }

        if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
            factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
        }

        if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
            factory.setMapperLocations(this.properties.resolveMapperLocations());
        }

        return factory.getObject();
    }

epilogue

Through the above analysis of mybatis how to integrate spring boot, know where the springboot entrance and how to achieve automatic configuration, here is just a brief introduction, some of the source code and details have not been analyzed, I believe, the entrance knows, then it is good to cut out the details.

I also opened the Wechat Public Number: stonezplxjj. More articles are welcome to pay attention to the Public Number:

Posted by el_quijote on Tue, 23 Apr 2019 17:33:35 -0700