中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring Boot自動注入的原理分析

發布時間:2020-09-08 17:09:34 來源:腳本之家 閱讀:205 作者:李斯特王 欄目:編程語言

前言

我們經常會被問到這么一個問題:SpringBoot相對于spring有哪些優勢呢?其中有一條答案就是SpringBoot自動注入。那么自動注入的原理是什么呢?

我們進行如下分析。

1:首先我們分析項目的啟動類時,發現都會加上@SpringBootApplication這個注解,我們分析這個繼續進入這個注解會發現,它是由多個注解組成的,如下

@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 {

2:服務啟動會掃描 org.springframework.boot.autoconfigure下的 META-INF/spring.factories 這個文件,這個文件中保存著springboot 啟動時默認會自動注入的類,部分如下

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h3.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth3.OAuth3AutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\
org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\
org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\
org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration

3:你是不是在其中發現了自己常用的redis,mysql等相關的類?沒錯,springboot會嘗試加載這些類,我們以 org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration 這個類為例,進去看一下它的源碼,部分示例如下

@Configuration
@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {

 /**
  * Redis connection configuration.
  */
 @Configuration
 @ConditionalOnClass(GenericObjectPool.class)
 protected static class RedisConnectionConfiguration {

  private final RedisProperties properties;

  private final RedisSentinelConfiguration sentinelConfiguration;

  private final RedisClusterConfiguration clusterConfiguration;

  public RedisConnectionConfiguration(RedisProperties properties,
    ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
    ObjectProvider<RedisClusterConfiguration> clusterConfiguration) {
   this.properties = properties;
   this.sentinelConfiguration = sentinelConfiguration.getIfAvailable();
   this.clusterConfiguration = clusterConfiguration.getIfAvailable();
  }

  @Bean
  @ConditionalOnMissingBean(RedisConnectionFactory.class)
  public JedisConnectionFactory redisConnectionFactory()
    throws UnknownHostException {
   return applyProperties(createJedisConnectionFactory());
  }

我們能看到這個類上加了這個注解 @ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class }) 意思就是如果你的classpath中沒有這些類的話,那么這個類就不能被加載,那么這些被依賴的類在哪出現呢?沒錯,就在我們在pom.xml中引入的依賴所對應的包里。

看到這里你因該就明白了,META-INF/spring.factories 文件中被列出來的那些類都會被springboot去嘗試加載,但是有些模塊我們沒引入相關的依賴,那么這個類就會加載失敗。即這個模塊沒有被成功加載。

4:我們通過上面的redis的自動加載類時,看到上面還有個 @EnableConfigurationProperties(RedisProperties.class) 注解,這個注解來注入關于redis的配置信息,這個信息都在 RedisProperties.class 中保存,我們看下 RedisProperties的源碼

@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {

  /**
   * Database index used by the connection factory.
   */
  private int database = 0;

  /**
   * Redis url, which will overrule host, port and password if set.
   */
  private String url;

  /**
   * Redis server host.
   */
  private String host = "localhost";

  /**
   * Login password of the redis server.
   */
  private String password;

  /**
   * Redis server port.
   */
  private int port = 6379;

  /**
   * Enable SSL.
   */
  private boolean ssl;

  /**
   * Connection timeout in milliseconds.
   */
  private int timeout;

  private Pool pool;

  private Sentinel sentinel;

  private Cluster cluster;

  public int getDatabase() {
    return this.database;
  }

  public void setDatabase(int database) {
    this.database = database;
  }

  public String getUrl() {
    return this.url;
  }

  public void setUrl(String url) {
    this.url = url;
  }

  public String getHost() {
    return this.host;
  }

  public void setHost(String host) {
    this.host = host;
  }

  public String getPassword() {
    return this.password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public int getPort() {
    return this.port;
  }

  public void setPort(int port) {
    this.port = port;
  }

  public boolean isSsl() {
    return this.ssl;
  }

  public void setSsl(boolean ssl) {
    this.ssl = ssl;
  }

  public void setTimeout(int timeout) {
    this.timeout = timeout;
  }

  public int getTimeout() {
    return this.timeout;
  }

  public Sentinel getSentinel() {
    return this.sentinel;
  }

  public void setSentinel(Sentinel sentinel) {
    this.sentinel = sentinel;
  }

  public Pool getPool() {
    return this.pool;
  }

  public void setPool(Pool pool) {
    this.pool = pool;
  }

  public Cluster getCluster() {
    return this.cluster;
  }

  public void setCluster(Cluster cluster) {
    this.cluster = cluster;
  }

  /**
   * Pool properties.
   */
  public static class Pool {

    /**
     * Max number of "idle" connections in the pool. Use a negative value to indicate
     * an unlimited number of idle connections.
     */
    private int maxIdle = 8;

    /**
     * Target for the minimum number of idle connections to maintain in the pool. This
     * setting only has an effect if it is positive.
     */
    private int minIdle = 0;

    /**
     * Max number of connections that can be allocated by the pool at a given time.
     * Use a negative value for no limit.
     */
    private int maxActive = 8;

    /**
     * Maximum amount of time (in milliseconds) a connection allocation should block
     * before throwing an exception when the pool is exhausted. Use a negative value
     * to block indefinitely.
     */
    private int maxWait = -1;

    public int getMaxIdle() {
      return this.maxIdle;
    }

    public void setMaxIdle(int maxIdle) {
      this.maxIdle = maxIdle;
    }

    public int getMinIdle() {
      return this.minIdle;
    }

    public void setMinIdle(int minIdle) {
      this.minIdle = minIdle;
    }

    public int getMaxActive() {
      return this.maxActive;
    }

    public void setMaxActive(int maxActive) {
      this.maxActive = maxActive;
    }

    public int getMaxWait() {
      return this.maxWait;
    }

    public void setMaxWait(int maxWait) {
      this.maxWait = maxWait;
    }

  }

  /**
   * Cluster properties.
   */
  public static class Cluster {

    /**
     * Comma-separated list of "host:port" pairs to bootstrap from. This represents an
     * "initial" list of cluster nodes and is required to have at least one entry.
     */
    private List<String> nodes;

    /**
     * Maximum number of redirects to follow when executing commands across the
     * cluster.
     */
    private Integer maxRedirects;

    public List<String> getNodes() {
      return this.nodes;
    }

    public void setNodes(List<String> nodes) {
      this.nodes = nodes;
    }

    public Integer getMaxRedirects() {
      return this.maxRedirects;
    }

    public void setMaxRedirects(Integer maxRedirects) {
      this.maxRedirects = maxRedirects;
    }

  }

  /**
   * Redis sentinel properties.
   */
  public static class Sentinel {

    /**
     * Name of Redis server.
     */
    private String master;

    /**
     * Comma-separated list of host:port pairs.
     */
    private String nodes;

    public String getMaster() {
      return this.master;
    }

    public void setMaster(String master) {
      this.master = master;
    }

    public String getNodes() {
      return this.nodes;
    }

    public void setNodes(String nodes) {
      this.nodes = nodes;
    }

  }

}

發現里面的配置項基本都是有默認值的,通過上面的注解可以明白,如果配置文件中存在 spring.redis 開頭的配置項,則使用配置文件中的,如果沒有的話則使用文件中默認寫死的配置。你是不是想到了springboot的另外一個優勢:約定大于配置。

這里我們大概了解了SpringBoot自動配置的原理和流程,里面的那些細節我們不在分析。同理,對于那些第三方或者我們自己寫的starter,springboot啟動的時候會掃描starter的jar包下 META-INF/spring.factories 這個文件,解析內容并加載里面對用的類。

由此,我們總結出以下幾點

  1:SpringBoot的自動配置是如何實現的

  2:有關的那些注解,如@EnableAutoConfiguration, @ConditionalOnClass, @Configuration等也是SpringBoot的核心注解,也值得我們了解其用法和原理。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

湖南省| 寿宁县| 枞阳县| 霸州市| 富源县| 定日县| 体育| 临城县| 洛浦县| 泰和县| 海城市| 衡南县| 民权县| 马鞍山市| 朝阳县| 朝阳市| 深水埗区| 察雅县| 平南县| 固阳县| 元谋县| 巴林右旗| 永寿县| 通辽市| 通山县| 林甸县| 昌都县| 和平区| 江源县| 郯城县| 界首市| 琼海市| 双峰县| 胶州市| 兰考县| 上杭县| 喀喇沁旗| 清水县| 祁连县| 临夏市| 南陵县|