這篇文章主要介紹“SpringBoot自動(dòng)裝配的方法步驟”,在日常操作中,相信很多人在SpringBoot自動(dòng)裝配的方法步驟問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”SpringBoot自動(dòng)裝配的方法步驟”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
為屏邊等地區(qū)用戶(hù)提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及屏邊網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、屏邊網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專(zhuān)業(yè)、用心的態(tài)度為用戶(hù)提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶(hù)的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!首先闡明,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:
@Configurationpublic class AppConfig { @Bean public SampleService sampleService() { return new SampleServiceImpl(); }}
@Bean注解用于修飾方法,方法的返回值會(huì)作為一個(gè)bean裝載到spring容器中。bean的id就是方法的名字。
@Configuration注解用于修飾一個(gè)類(lèi),它表明這個(gè)類(lèi)的作用是用來(lái)對(duì)spring容器進(jìn)行配置的。
上面的Java代碼相當(dāng)于下面的XML配置:
<beans> <bean id="sampleService" class="com.**.SampleServiceImpl"/></beans>
使用AnnotationConfigApplicationContext類(lèi)構(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類(lèi)還提供了scan方法用于指定要掃描的包路徑。我們可以刪除AppConfig類(lèi)上的@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è)類(lèi)中肯定是不合適的,這會(huì)導(dǎo)致那個(gè)配置類(lèi)非常復(fù)雜。通常會(huì)創(chuàng)建多個(gè)配置類(lèi),再借助@Import將多個(gè)配置類(lèi)組合成一個(gè)。@Import的功能類(lèi)似于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(); }}
上面的代碼分別創(chuàng)建了兩個(gè)配置類(lèi)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è)配置類(lèi),但同時(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è)配置類(lèi)。當(dāng)有多個(gè)配置類(lèi)需要同時(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á)條件的類(lèi)SampleCondition,接下來(lái)我們就可以通過(guò)@Conditional注解對(duì)創(chuàng)建bean的函數(shù)進(jìn)行配置:
請(qǐng)輸入代碼@Configuration
public class ConditionConfig { // 只有當(dāng)滿(mǎn)足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è)類(lèi)在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類(lèi)。
@SpringBootApplication注解
介紹完前面這些基礎(chǔ)的知識(shí)后,我們來(lái)看Spring Boot是如何實(shí)現(xiàn)自動(dòng)裝配的?!禨pring 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)注的類(lèi)提供了Spring Boot應(yīng)用的配置,其實(shí)這個(gè)注解與@Configuration注解的功能類(lèi)似。@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配置類(lèi),我們截取幾個(gè)重要的配置類(lèi)如下(已經(jīng)刪除了很多):
# 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類(lèi),有Spring Framework的、Web的、redis的、JDBC的等等。我們從其中選擇HttpEncodingAutoConfiguration這個(gè)類(lèi)來(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; }
上面代碼表示,只有在滿(mǎn)足如下條件時(shí),才會(huì)注入characterEncodingFilter這個(gè)bean:
只有在WebApplication的情況 classpath上必須存在CharacterEncodingFilter類(lèi) 配置文件中配置了spring.http.encoding.enabled為true或者沒(méi)有配置 Spring容器中不存在類(lèi)型為CharacterEncodingFilter的bean
總結(jié)
Spring Boot自動(dòng)裝配的原理并不是非常復(fù)雜,其實(shí)背后的主要原理就是條件注解。
當(dāng)我們使用@EnableAutoConfiguration注解激活自動(dòng)裝配時(shí),實(shí)質(zhì)對(duì)應(yīng)著很多XXXAutoConfiguration類(lèi)在執(zhí)行裝配工作,這些XXXAutoConfiguration類(lèi)是在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類(lèi)中,都會(huì)利用多種類(lèi)型的條件注解@ConditionOnXXX對(duì)當(dāng)前的應(yīng)用環(huán)境做判斷,如應(yīng)用程序是否為Web應(yīng)用、classpath路徑上是否包含對(duì)應(yīng)的類(lèi)、Spring容器中是否已經(jīng)包含了對(duì)應(yīng)類(lèi)型的bean。如果判斷條件都成立,XXXAutoConfiguration就會(huì)認(rèn)為需要向Spring容器中注入這個(gè)bean,否則就忽略。
到此,關(guān)于“SpringBoot自動(dòng)裝配的方法步驟”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
文章標(biāo)題:SpringBoot自動(dòng)裝配的方法步驟-創(chuàng)新互聯(lián)
當(dāng)前鏈接:http://jinyejixie.com/article2/pihic.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、全網(wǎng)營(yíng)銷(xiāo)推廣、ChatGPT、虛擬主機(jī)、標(biāo)簽優(yōu)化、做網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容