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

溫馨提示×

溫馨提示×

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

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

SpringBoot自動裝配的方法步驟

發布時間:2021-08-06 10:50:00 來源:億速云 閱讀:199 作者:chen 欄目:編程語言

這篇文章主要介紹“SpringBoot自動裝配的方法步驟”,在日常操作中,相信很多人在SpringBoot自動裝配的方法步驟問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”SpringBoot自動裝配的方法步驟”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

首先闡明,spring boot的自動配置是基于spring framework提供的特性實現的,所以在本文中,我們先介紹spring framework的相關特性,在了解了這些基礎知識后,我們再來看spring boot的自動配置是如何實現的。

基于Java代碼對Spring進行配置

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

除了使用XML對spring進行配置,還可以使用Java代碼執行完全相同的配置。下面我們詳細看一下如何使用Java代碼對spring容器進行配置,詳細內容可參考這里。

使用Java代碼進行spring配置,有兩個核心注解@Configuration和@Bean:

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

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

@Configuration注解用于修飾一個類,它表明這個類的作用是用來對spring容器進行配置的。

上面的Java代碼相當于下面的XML配置:

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

使用AnnotationConfigApplicationContext類構建一個spring容器,從容器中取出對應的bean的測試代碼如下:

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代碼相當于下面的XML配置:

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

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

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組合多個配置

將所有的spring配置全部放在同一個類中肯定是不合適的,這會導致那個配置類非常復雜。通常會創建多個配置類,再借助@Import將多個配置類組合成一個。@Import的功能類似于XML中的<import/>。

@Configurationpublic class ConfigA {  @Bean  public A a() {    return new A();  }}@Configuration@Import(ConfigA.class)public class ConfigB {  @Bean  public B b() {    return new B();  }}

上面的代碼分別創建了兩個配置類ConfigA和ConfigB,它們分別定義了a和b兩個Bean。在ConfigB上使用@Import注解導入ConfigA的配置,此時應用代碼如果加載ConfigB的配置,就自動也加載了ConfigA的配置。如下代碼所示:

public static void main(String[] args) {  // 只加載ConfigB一個配置類,但同時也包含了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還可以同時導入多個配置類。當有多個配置類需要同時導入時,示意代碼如下:

@Configuration@Import({ServiceConfig.class, RepositoryConfig.class})public class SystemTestConfig {  @Bean  public DataSource dataSource() {    // return new DataSource  }}

條件注解@Conditional

@Conditional注解根據某一個條件是否成立來判斷是否構建Bean。借助Condition接口可以表示一個特定條件。例如下面代碼實現了一個條件,當然這個條件始終成立:

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

有了表達條件的類SampleCondition,接下來我們就可以通過@Conditional注解對創建bean的函數進行配置:

請輸入代碼@Configuration

public class ConditionConfig {  // 只有當滿足SampleCondition指定的條件時,參會構造id時sampleBean這個bean。當然這里的條件始終成立  @Conditional(SampleCondition.class)  @Bean  public SampleBean sampleBean() {    return new SampleBean();  }}

由于SampleCondition的matches方法返回true,表示創建bean的條件成立,所以sampleBean會被創建。如果matches返回false,sampleBean就不會被構建。

在spring boot中,根據這個原理提供了很多@ConditionOnXXX的注解,這些注解都在包org.springframework.boot.autoconfigure.condition下面。例如比較常見的@ConditionalOnClass注解,這個注解的判斷邏輯是只有指定的某個類在classpath上存在時,判斷條件才成立。@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注解

介紹完前面這些基礎的知識后,我們來看Spring Boot是如何實現自動裝配的。《Spring Boot官方文檔第14章》推薦在程序的main class上使用注解@SpringBootApplication對Spring應用進行自動配置,我們就從分析這個注解開始。下面是@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是一個組合注解,主要由@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三個注解構成。

@SpringBootConfiguration表明被標注的類提供了Spring Boot應用的配置,其實這個注解與@Configuration注解的功能類似。@ComponentScan指定需要掃描package的路徑,@SpringBootApplication也提供了相應屬性,指定需要掃描哪些package或不掃描哪些package。《Spring Boot官方文檔》建議將應用的main class放置于整個工程的根路徑,并用@SpringBootApplication注解修飾main class,這樣整個項目的子package就都會被自動掃描包含。建議的工程結構如下所示,其中Application就是應用的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是這里最重要的注解,它實現了對Spring Boot應用自動裝配的功能。@EnableAutoConfiguration是利用SpringFactoriesLoader機制加載自動裝配配置的,它的配置數據在META-INF/spring.factories中,我們打開spring-boot-autoconfigure jar中的該文件,發現EnableAutoConfiguration對應著N多XXXAutoConfiguration配置類,我們截取幾個重要的配置類如下(已經刪除了很多):

# Auto Configureorg.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.h3.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這個類來看下它是如何實現自動配置的:

@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;  }

上面代碼表示,只有在滿足如下條件時,才會注入characterEncodingFilter這個bean:

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

總結

Spring Boot自動裝配的原理并不是非常復雜,其實背后的主要原理就是條件注解。

當我們使用@EnableAutoConfiguration注解激活自動裝配時,實質對應著很多XXXAutoConfiguration類在執行裝配工作,這些XXXAutoConfiguration類是在spring-boot-autoconfigure jar中的META-INF/spring.factories文件中配置好的,@EnableAutoConfiguration通過SpringFactoriesLoader機制創建XXXAutoConfiguration這些bean。XXXAutoConfiguration的bean會依次執行并判斷是否需要創建對應的bean注入到Spring容器中。

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

到此,關于“SpringBoot自動裝配的方法步驟”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

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

AI

乡宁县| 若羌县| 磐石市| 平邑县| 安阳市| 扬州市| 花莲县| 行唐县| 梁河县| 平邑县| 家居| 井冈山市| 科技| 闽清县| 阜康市| 浠水县| 涞源县| 安徽省| 丹巴县| 太白县| 朔州市| 大安市| 达日县| 车险| 二手房| 延边| 西畴县| 白银市| 娄烦县| 辛集市| 奈曼旗| 高尔夫| 小金县| 孟津县| 绍兴市| 东乌珠穆沁旗| 绥滨县| 洱源县| 龙井市| 西青区| 宣恩县|