亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Spring Boot自動(dòng)裝配的方法步驟

 更新時(shí)間:2019年06月10日 09:27:57   作者:poype  
這篇文章主要介紹了詳解Spring Boot自動(dòng)裝配的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

在《Spring Boot Hello World》中介紹了一個(gè)簡(jiǎn)單的spring boot例子,體驗(yàn)了spring boot中的諸多特性,其中的自動(dòng)配置特性極大的簡(jiǎn)化了程序開(kāi)發(fā)中的工作(不用寫一行XML)。本文我們就來(lái)看一下spring boot是如何做到自動(dòng)配置的。
首先闡明,spring boot的自動(dòng)配置是基于spring framework提供的特性實(shí)現(xiàn)的,所以在本文中,我們先介紹spring framework的相關(guān)特性,在了解了這些基礎(chǔ)知識(shí)后,我們?cè)賮?lái)看spring boot的自動(dòng)配置是如何實(shí)現(xiàn)的。

基于Java代碼對(duì)Spring進(jìn)行配置

在以往使用spring framework進(jìn)行程序開(kāi)發(fā)時(shí),相信大家也只是使用XML搭配注解的方式對(duì)spring容器進(jìn)行配置,例如在XML文件中使用<context:component-scan base-package="**"/>指定spring需要掃描package的根路徑。

除了使用XML對(duì)spring進(jìn)行配置,還可以使用Java代碼執(zhí)行完全相同的配置。下面我們?cè)敿?xì)看一下如何使用Java代碼對(duì)spring容器進(jìn)行配置,詳細(xì)內(nèi)容可參考這里。

使用Java代碼進(jìn)行spring配置,有兩個(gè)核心注解@Configuration和@Bean:

@Configuration
public class AppConfig {

  @Bean
  public SampleService sampleService() {
    return new SampleServiceImpl();
  }
}

@Bean注解用于修飾方法,方法的返回值會(huì)作為一個(gè)bean裝載到spring容器中。bean的id就是方法的名字。

@Configuration注解用于修飾一個(gè)類,它表明這個(gè)類的作用是用來(lái)對(duì)spring容器進(jìn)行配置的。

上面的Java代碼相當(dāng)于下面的XML配置:

<beans>
  <bean id="sampleService" class="com.**.SampleServiceImpl"/>
</beans>

使用AnnotationConfigApplicationContext類構(gòu)建一個(gè)spring容器,從容器中取出對(duì)應(yīng)的bean的測(cè)試代碼如下:

public static void main(String[] args) {
  ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
  SampleService myService = ctx.getBean("sampleService" ,SampleService.class);
  myService.doService();
}

Java代碼配置ComponentScan

使用@ComponentScan注解指定需要掃描package的根路徑:

@Configuration
@ComponentScan(basePackages = "com.**.service.impl")
public class AppConfig {

}

上面的Java代碼相當(dāng)于下面的XML配置:

<beans>
  <context:component-scan base-package="com.**.service.impl"/>
</beans>

此外,AnnotationConfigApplicationContext類還提供了scan方法用于指定要掃描的包路徑。我們可以刪除AppConfig類上的@ComponentScan注解,在構(gòu)造spring容器時(shí)使用下面代碼:

public static void main(String[] args) {
  AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
  ctx.scan("com.**.service.impl");
  ctx.refresh();
  SampleService myService = ctx.getBean("sampleService" ,SampleService.class);
  myService.doService();
}

使用@Import組合多個(gè)配置

將所有的spring配置全部放在同一個(gè)類中肯定是不合適的,這會(huì)導(dǎo)致那個(gè)配置類非常復(fù)雜。通常會(huì)創(chuàng)建多個(gè)配置類,再借助@Import將多個(gè)配置類組合成一個(gè)。@Import的功能類似于XML中的<import/>。

@Configuration
public class ConfigA {

  @Bean
  public A a() {
    return new A();
  }
}

@Configuration
@Import(ConfigA.class)
public class ConfigB {

  @Bean
  public B b() {
    return new B();
  }
}

上面的代碼分別創(chuàng)建了兩個(gè)配置類ConfigA和ConfigB,它們分別定義了a和b兩個(gè)Bean。在ConfigB上使用@Import注解導(dǎo)入ConfigA的配置,此時(shí)應(yīng)用代碼如果加載ConfigB的配置,就自動(dòng)也加載了ConfigA的配置。如下代碼所示:

public static void main(String[] args) {
  // 只加載ConfigB一個(gè)配置類,但同時(shí)也包含了ConfigA的配置
  ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);

  A a = ctx.getBean(A.class);
  B b = ctx.getBean(B.class);

  System.out.println(a);
  System.out.println(b);
}

@Import還可以同時(shí)導(dǎo)入多個(gè)配置類。當(dāng)有多個(gè)配置類需要同時(shí)導(dǎo)入時(shí),示意代碼如下:

@Configuration
@Import({ServiceConfig.class, RepositoryConfig.class})
public class SystemTestConfig {

  @Bean
  public DataSource dataSource() {
    // return new DataSource
  }
}

條件注解@Conditional

@Conditional注解根據(jù)某一個(gè)條件是否成立來(lái)判斷是否構(gòu)建Bean。借助Condition接口可以表示一個(gè)特定條件。例如下面代碼實(shí)現(xiàn)了一個(gè)條件,當(dāng)然這個(gè)條件始終成立:

public class SampleCondition implements Condition {

  @Override
  public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
    // 如果條件成立返回true, 反之返回false
    return true;
  }
}

有了表達(dá)條件的類SampleCondition,接下來(lái)我們就可以通過(guò)@Conditional注解對(duì)創(chuàng)建bean的函數(shù)進(jìn)行配置:

請(qǐng)輸入代碼@Configuration

public class ConditionConfig {

  // 只有當(dāng)滿足SampleCondition指定的條件時(shí),參會(huì)構(gòu)造id時(shí)sampleBean這個(gè)bean。當(dāng)然這里的條件始終成立
  @Conditional(SampleCondition.class)
  @Bean
  public SampleBean sampleBean() {
    return new SampleBean();
  }
}

由于SampleCondition的matches方法返回true,表示創(chuàng)建bean的條件成立,所以sampleBean會(huì)被創(chuàng)建。如果matches返回false,sampleBean就不會(huì)被構(gòu)建。

在spring boot中,根據(jù)這個(gè)原理提供了很多@ConditionOnXXX的注解,這些注解都在包org.springframework.boot.autoconfigure.condition下面。例如比較常見(jiàn)的@ConditionalOnClass注解,這個(gè)注解的判斷邏輯是只有指定的某個(gè)類在classpath上存在時(shí),判斷條件才成立。@ConditionalOnClass的具體代碼如下:

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass {

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

  String[] name() default {};
}

@ConditionalOnClass具體的判斷邏輯可參看OnClassCondition類。

@SpringBootApplication注解

介紹完前面這些基礎(chǔ)的知識(shí)后,我們來(lái)看Spring Boot是如何實(shí)現(xiàn)自動(dòng)裝配的。
Spring Boot官方文檔第14章》推薦在程序的main class上使用注解@SpringBootApplication對(duì)Spring應(yīng)用進(jìn)行自動(dòng)配置,我們就從分析這個(gè)注解開(kāi)始。下面是@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 {
  // ...

@SpringBootApplication是一個(gè)組合注解,主要由@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三個(gè)注解構(gòu)成。

@SpringBootConfiguration表明被標(biāo)注的類提供了Spring Boot應(yīng)用的配置,其實(shí)這個(gè)注解與@Configuration注解的功能類似。
@ComponentScan指定需要掃描package的路徑,@SpringBootApplication也提供了相應(yīng)屬性,指定需要掃描哪些package或不掃描哪些package?!禨pring Boot官方文檔》建議將應(yīng)用的main class放置于整個(gè)工程的根路徑,并用@SpringBootApplication注解修飾main class,這樣整個(gè)項(xiàng)目的子package就都會(huì)被自動(dòng)掃描包含。建議的工程結(jié)構(gòu)如下所示,其中Application就是應(yīng)用的main class。

com
 +- example
   +- myapplication
     +- Application.java
     |
     +- customer
     |  +- Customer.java
     |  +- CustomerController.java
     |  +- CustomerService.java
     |  +- CustomerRepository.java
     |
     +- order
       +- Order.java
       +- OrderController.java
       +- OrderService.java
       +- OrderRepository.java

@EnableAutoConfiguration是這里最重要的注解,它實(shí)現(xiàn)了對(duì)Spring Boot應(yīng)用自動(dòng)裝配的功能。@EnableAutoConfiguration是利用SpringFactoriesLoader機(jī)制加載自動(dòng)裝配配置的,它的配置數(shù)據(jù)在META-INF/spring.factories中,我們打開(kāi)spring-boot-autoconfigure jar中的該文件,發(fā)現(xiàn)EnableAutoConfiguration對(duì)應(yīng)著N多XXXAutoConfiguration配置類,我們截取幾個(gè)重要的配置類如下(已經(jīng)刪除了很多):

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
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.CloudServiceConnectorsAutoConfiguration,\
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.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
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.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.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
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.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\

可以看到Spring Boot提供了N多XXXAutoConfiguration類,有Spring Framework的、Web的、redis的、JDBC的等等。
我們從其中選擇HttpEncodingAutoConfiguration這個(gè)類來(lái)看下它是如何實(shí)現(xiàn)自動(dòng)配置的:

@Configuration
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled",
    matchIfMissing = true)
public class HttpEncodingAutoConfiguration {

  private final HttpProperties.Encoding properties;

  public HttpEncodingAutoConfiguration(HttpProperties properties) {
    this.properties = properties.getEncoding();
  }

  @Bean
  @ConditionalOnMissingBean
  public CharacterEncodingFilter characterEncodingFilter() {
    CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
    filter.setEncoding(this.properties.getCharset().name());
    filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
    filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
    return filter;
  }

上面代碼表示,只有在滿足如下條件時(shí),才會(huì)注入characterEncodingFilter這個(gè)bean:

  1. 只有在WebApplication的情況
  2. classpath上必須存在CharacterEncodingFilter類
  3. 配置文件中配置了spring.http.encoding.enabled為true或者沒(méi)有配置
  4. Spring容器中不存在類型為CharacterEncodingFilter的bean

總結(jié)

Spring Boot自動(dòng)裝配的原理并不是非常復(fù)雜,其實(shí)背后的主要原理就是條件注解。

當(dāng)我們使用@EnableAutoConfiguration注解激活自動(dòng)裝配時(shí),實(shí)質(zhì)對(duì)應(yīng)著很多XXXAutoConfiguration類在執(zhí)行裝配工作,這些XXXAutoConfiguration類是在spring-boot-autoconfigure jar中的META-INF/spring.factories文件中配置好的,@EnableAutoConfiguration通過(guò)SpringFactoriesLoader機(jī)制創(chuàng)建XXXAutoConfiguration這些bean。XXXAutoConfiguration的bean會(huì)依次執(zhí)行并判斷是否需要?jiǎng)?chuàng)建對(duì)應(yīng)的bean注入到Spring容器中。

在每個(gè)XXXAutoConfiguration類中,都會(huì)利用多種類型的條件注解@ConditionOnXXX對(duì)當(dāng)前的應(yīng)用環(huán)境做判斷,如應(yīng)用程序是否為Web應(yīng)用、classpath路徑上是否包含對(duì)應(yīng)的類、Spring容器中是否已經(jīng)包含了對(duì)應(yīng)類型的bean。如果判斷條件都成立,XXXAutoConfiguration就會(huì)認(rèn)為需要向Spring容器中注入這個(gè)bean,否則就忽略。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java8新特性:Lambda表達(dá)式之方法引用詳解

    Java8新特性:Lambda表達(dá)式之方法引用詳解

    這篇文章主要給大家介紹了關(guān)于Java8新特性:Lambda表達(dá)式之方法引用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • IDEA操作MongoDB及安全認(rèn)證方式

    IDEA操作MongoDB及安全認(rèn)證方式

    這篇文章主要介紹了IDEA操作MongoDB及安全認(rèn)證方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Java基于正則實(shí)現(xiàn)的日期校驗(yàn)功能示例

    Java基于正則實(shí)現(xiàn)的日期校驗(yàn)功能示例

    這篇文章主要介紹了Java基于正則實(shí)現(xiàn)的日期校驗(yàn)功能,涉及java文件讀取、日期轉(zhuǎn)換及字符串正則匹配相關(guān)操作技巧,需要的朋友可以參考下
    2017-03-03
  • Java?@Accessors注解圖文詳解

    Java?@Accessors注解圖文詳解

    @Accessors用于改變@Data生成的getter和setter方法的生成結(jié)果,下面這篇文章主要給大家介紹了關(guān)于Java?@Accessors注解的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • Security中的@PostAuthorize、@PreFilter和@PostFilter詳解

    Security中的@PostAuthorize、@PreFilter和@PostFilter詳解

    這篇文章主要介紹了Security中的@PostAuthorize、@PreFilter和@PostFilter詳解,@PostAuthorize是在方法調(diào)用完成后進(jìn)行權(quán)限檢查,它不能控制方法是否能被調(diào)用,只能在方法調(diào)用完成后檢查權(quán)限決定是否要拋出AccessDeniedException,需要的朋友可以參考下
    2023-11-11
  • 基于ArrayList常用方法的源碼全面解析

    基于ArrayList常用方法的源碼全面解析

    下面小編就為大家?guī)?lái)一篇基于ArrayList常用方法的源碼全面解析。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Java編程二項(xiàng)分布的遞歸和非遞歸實(shí)現(xiàn)代碼實(shí)例

    Java編程二項(xiàng)分布的遞歸和非遞歸實(shí)現(xiàn)代碼實(shí)例

    這篇文章主要介紹了Java編程二項(xiàng)分布的遞歸和非遞歸實(shí)現(xiàn)代碼實(shí)例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)

    Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn)

    這篇文章主要介紹了Spring Security OAuth2 授權(quán)碼模式的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • mysql+mybatis下全文搜索的使用方法

    mysql+mybatis下全文搜索的使用方法

    本文主要介紹了mysql+mybatis下全文搜索的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • java使用OpenCV從視頻文件中獲取幀

    java使用OpenCV從視頻文件中獲取幀

    這篇文章主要為大家詳細(xì)介紹了java使用OpenCV從視頻文件中獲取幀,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07

最新評(píng)論