`

理解@Springbootapplicaion和自动装配机制

 
阅读更多

1 @SpringBootApplication理解

   @SpringBootApplication是一个合成注解,他是@EnableAutoConfiguration,@Configuration,@ComponentScane,3个的合成注解,

@EnableAutoConfiguration注解,可以帮助springBoot应用将所有符合条件的@Configuration都加载到当前springBoot创建并使用的IOC容器中

@Configuration注解是一个派生注解,它是@Component的子注解, 它还有一个@SpringBootConfiguration的子注解

@ComponentScan:SpringBoot应用使用@ComponentScan的方式装载@Configuration类

@SpringBootApplication注解中使用了@Aliasfor注解,该注解可以将其他注解的属性别名在自己的属性中,从而像使用自己的注解属性一样使用????

 

2 自动装配机制理解

  当DataSourceAutoConfiguration.EmbededDatabaseCondition匹配后,即HSQLDB的JDBC驱动类org.hsqldb.jdbcDriver存在于Class Path下时,@Configuration类DataSourceAutoConfiguration.EmbededDatabaseConfiguraion将被装配,故EmbeddedDataSourceConfiguration将被@Import注解导入

 1  

  //

// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.boot.autoconfigure.jdbc;
import javax.sql.DataSource;
import javax.sql.XADataSource;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.autoconfigure.condition.ConditionMessage.Builder;
import org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.Dbcp2;
import org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.Generic;
import org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.Hikari;
import org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.Tomcat;
import org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
@Configuration
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@EnableConfigurationProperties({DataSourceProperties.class})
@Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class})
public class DataSourceAutoConfiguration {
public DataSourceAutoConfiguration() {
    }
static class EmbeddedDatabaseCondition extends SpringBootCondition {
private final SpringBootCondition pooledCondition = new DataSourceAutoConfiguration.PooledDataSourceCondition();
EmbeddedDatabaseCondition() {
        }
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
Builder message = ConditionMessage.forCondition("EmbeddedDataSource", new Object[0]);
if (this.anyMatches(context, metadata, new Condition[]{this.pooledCondition})) {
return ConditionOutcome.noMatch(message.foundExactly("supported pooled data source"));
            } else {
EmbeddedDatabaseType type = EmbeddedDatabaseConnection.get(context.getClassLoader()).getType();
return type == null ? ConditionOutcome.noMatch(message.didNotFind("embedded database").atAll()) : ConditionOutcome.match(message.found("embedded database").items(new Object[]{type}));
            }
        }
    }
static class PooledDataSourceAvailableCondition extends SpringBootCondition {
PooledDataSourceAvailableCondition() {
        }
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
Builder message = ConditionMessage.forCondition("PooledDataSource", new Object[0]);
return this.getDataSourceClassLoader(context) != null ? ConditionOutcome.match(message.foundExactly("supported DataSource")) : ConditionOutcome.noMatch(message.didNotFind("supported DataSource").atAll());
        }
private ClassLoader getDataSourceClassLoader(ConditionContext context) {
Class<?> dataSourceClass = DataSourceBuilder.findType(context.getClassLoader());
return dataSourceClass != null ? dataSourceClass.getClassLoader() : null;
        }
    }
static class PooledDataSourceCondition extends AnyNestedCondition {
PooledDataSourceCondition() {
super(ConfigurationPhase.PARSE_CONFIGURATION);
        }
@Conditional({DataSourceAutoConfiguration.PooledDataSourceAvailableCondition.class})
static class PooledDataSourceAvailable {
PooledDataSourceAvailable() {
            }
        }
@ConditionalOnProperty(
prefix = "spring.datasource",
name = {"type"}
        )
static class ExplicitType {
ExplicitType() {
            }
        }
    }
@Configuration
    @Conditional({DataSourceAutoConfiguration.PooledDataSourceCondition.class})
@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
@Import({Hikari.class, Tomcat.class, Dbcp2.class, Generic.class, DataSourceJmxConfiguration.class})
protected static class PooledDataSourceConfiguration {
protected PooledDataSourceConfiguration() {
        }
    }
@Configuration
    @Conditional({DataSourceAutoConfiguration.EmbeddedDatabaseCondition.class})
@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
@Import({EmbeddedDataSourceConfiguration.class})
protected static class EmbeddedDatabaseConfiguration {
protected EmbeddedDatabaseConfiguration() {
        }
    }
}

  2 

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.boot.autoconfigure.jdbc;
import javax.sql.DataSource;
import javax.sql.XADataSource;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.autoconfigure.condition.ConditionMessage.Builder;
import org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.Dbcp2;
import org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.Generic;
import org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.Hikari;
import org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.Tomcat;
import org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
@Configuration
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@EnableConfigurationProperties({DataSourceProperties.class})
@Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class})
public class DataSourceAutoConfiguration {
public DataSourceAutoConfiguration() {
    }
static class EmbeddedDatabaseCondition extends SpringBootCondition {
private final SpringBootCondition pooledCondition = new DataSourceAutoConfiguration.PooledDataSourceCondition();
EmbeddedDatabaseCondition() {
        }
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
Builder message = ConditionMessage.forCondition("EmbeddedDataSource", new Object[0]);
if (this.anyMatches(context, metadata, new Condition[]{this.pooledCondition})) {
return ConditionOutcome.noMatch(message.foundExactly("supported pooled data source"));
            } else {
EmbeddedDatabaseType type = EmbeddedDatabaseConnection.get(context.getClassLoader()).getType();
return type == null ? ConditionOutcome.noMatch(message.didNotFind("embedded database").atAll()) : ConditionOutcome.match(message.found("embedded database").items(new Object[]{type}));
            }
        }
    }
static class PooledDataSourceAvailableCondition extends SpringBootCondition {
PooledDataSourceAvailableCondition() {
        }
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
Builder message = ConditionMessage.forCondition("PooledDataSource", new Object[0]);
return this.getDataSourceClassLoader(context) != null ? ConditionOutcome.match(message.foundExactly("supported DataSource")) : ConditionOutcome.noMatch(message.didNotFind("supported DataSource").atAll());
        }
private ClassLoader getDataSourceClassLoader(ConditionContext context) {
Class<?> dataSourceClass = DataSourceBuilder.findType(context.getClassLoader());
return dataSourceClass != null ? dataSourceClass.getClassLoader() : null;
        }
    }
static class PooledDataSourceCondition extends AnyNestedCondition {
PooledDataSourceCondition() {
super(ConfigurationPhase.PARSE_CONFIGURATION);
        }
@Conditional({DataSourceAutoConfiguration.PooledDataSourceAvailableCondition.class})
static class PooledDataSourceAvailable {
PooledDataSourceAvailable() {
            }
        }
@ConditionalOnProperty(
prefix = "spring.datasource",
name = {"type"}
        )
static class ExplicitType {
ExplicitType() {
            }
        }
    }
@Configuration
    @Conditional({DataSourceAutoConfiguration.PooledDataSourceCondition.class})
@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
@Import({Hikari.class, Tomcat.class, Dbcp2.class, Generic.class, DataSourceJmxConfiguration.class})
protected static class PooledDataSourceConfiguration {
protected PooledDataSourceConfiguration() {
        }
    }
@Configuration
    @Conditional({DataSourceAutoConfiguration.EmbeddedDatabaseCondition.class})
@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
@Import({EmbeddedDataSourceConfiguration.class})
protected static class EmbeddedDatabaseConfiguration {
protected EmbeddedDatabaseConfiguration() {
        }
    }
}

   

  不难看出,DataSourceAutoConfiguration和嵌套@Configuration类同样综合了@Configuration 类 和 @Conditional的特性,不过嵌套@Configuration类伴随着DataSourceAutoConfiguration的装配而装配,那么问题来了 DataSourceAutoConfiguration是如何被装配的

 spring-boot-autoconfiguration是spring boot核心模块,其中提供了大量的内建自动装配@Configuration类,他们统一放在org.springframework.boot.autoconfigure包或者子包下, 同时这些类均配置在META-INF/spring.factories资源中

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics