Spring Boot之自动配置AutoConfiguration(一)
2018-01-28 14:43
816 查看
使用Spring Boot的一个好处就是它提供了很多的Starter,可以帮助我们实现自动配置,极大的方便我们创建一个Spring应用。如果我们想创建一个自定义的Starter该如何入手呢?一个自动配置包含以下两个模块。
一、auto-configuration模块
一个auto-configuration模块包含了一个继承@Configuration的注解,通过@Conditional*条件注解来添加我们的自动配置类的约束条件。可以参考spring-boot-autoconfigure 模块的META-INF/spring.factories,里面是官方实现的一些自动配置类。
条件注解
@ConditionalOnClass:表示classpath存在相关的类才生效;
@ConditionalOnMissingClass:表示classpath存在相关的类不生效;
@ConditionalOnBean:表示如果存在相关Bean则该自动配置生效;
@ConditionalOnMissingBean:表示如果存在相关Bean则该自动配置不生效;
@ConditionalOnProperty:根据property条件约束;
@ConditionalOnResource:根据Resource条件约束;
@ConditionalOnExpression:根据SpEL表达式来约束;
二、starter模块
starter只是一个空的jar包,只有一个pom.xml文件,定义了该自动配置需要的依赖。
三、源码解析
如spring-cloud-commons模块里面的LoadBalancerAutoConfiguration
这里面就用到了我们上面提到那几个条件注解,通过这个自动配置,我们就可以在spring boot项目里面引入@LoadBalanced注解来实现客户端的负载均衡。
一、auto-configuration模块
一个auto-configuration模块包含了一个继承@Configuration的注解,通过@Conditional*条件注解来添加我们的自动配置类的约束条件。可以参考spring-boot-autoconfigure 模块的META-INF/spring.factories,里面是官方实现的一些自动配置类。
条件注解
@ConditionalOnClass:表示classpath存在相关的类才生效;
@ConditionalOnMissingClass:表示classpath存在相关的类不生效;
@ConditionalOnBean:表示如果存在相关Bean则该自动配置生效;
@ConditionalOnMissingBean:表示如果存在相关Bean则该自动配置不生效;
@ConditionalOnProperty:根据property条件约束;
@ConditionalOnResource:根据Resource条件约束;
@ConditionalOnExpression:根据SpEL表达式来约束;
二、starter模块
starter只是一个空的jar包,只有一个pom.xml文件,定义了该自动配置需要的依赖。
三、源码解析
如spring-cloud-commons模块里面的LoadBalancerAutoConfiguration
/* * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.cloud.client.loadbalancer; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.retry.support.RetryTemplate; import org.springframework.web.client.RestTemplate; /** * Auto configuration for Ribbon (client side load balancing). * * @author Spencer Gibb * @author Dave Syer * @author Will Tran */ @Configuration @ConditionalOnClass(RestTemplate.class) @ConditionalOnBean(LoadBalancerClient.class) @EnableConfigurationProperties(LoadBalancerRetryProperties.class) public class LoadBalancerAutoConfiguration { @LoadBalanced @Autowired(required = false) private List<RestTemplate> restTemplates = Collections.emptyList(); @Bean public SmartInitializingSingleton loadBalancedRestTemplateInitializer( final List<RestTemplateCustomizer> customizers) { return new SmartInitializingSingleton() { @Override public void afterSingletonsInstantiated() { for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) { for (RestTemplateCustomizer customizer : customizers) { customizer.customize(restTemplate); } } } }; } @Autowired(required = false) private List<LoadBalancerRequestTransformer> transformers = Collections.emptyList(); @Bean @ConditionalOnMissingBean public LoadBalancerRequestFactory loadBalancerRequestFactory( LoadBalancerClient loadBalancerClient) { return new LoadBalancerRequestFactory(loadBalancerClient, transformers); } @Configuration @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate") static class LoadBalancerInterceptorConfig { @Bean public LoadBalancerInterceptor ribbonInterceptor( LoadBalancerClient loadBalancerClient, LoadBalancerRequestFactory requestFactory) { return new LoadBalancerInterceptor(loadBalancerClient, requestFactory); } @Bean @ConditionalOnMissingBean public RestTemplateCustomizer restTemplateCustomizer( final LoadBalancerInterceptor loadBalancerInterceptor) { return new RestTemplateCustomizer() { @Override public void customize(RestTemplate restTemplate) { List<ClientHttpRequestInterceptor> list = new ArrayList<>( restTemplate.getInterceptors()); list.add(loadBalancerInterceptor); restTemplate.setInterceptors(list); } }; } } @Configuration @ConditionalOnClass(RetryTemplate.class) public static class RetryAutoConfiguration { @Bean public RetryTemplate retryTemplate() { RetryTemplate template = new RetryTemplate(); template.setThrowLastExceptionOnExhausted(true); return template; } @Bean @ConditionalOnMissingBean public LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory() { return new LoadBalancedRetryPolicyFactory.NeverRetryFactory(); } @Bean @ConditionalOnMissingBean public LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory() { return new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory(); } } @Configuration @ConditionalOnClass(RetryTemplate.class) public static class RetryInterceptorAutoConfiguration { @Bean @ConditionalOnMissingBean public RetryLoadBalancerInterceptor ribbonInterceptor( LoadBalancerClient loadBalancerClient, LoadBalancerRetryProperties properties, LoadBalancedRetryPolicyFactory lbRetryPolicyFactory, LoadBalancerRequestFactory requestFactory, LoadBalancedBackOffPolicyFactory backOffPolicyFactory) { return new RetryLoadBalancerInterceptor(loadBalancerClient, properties, lbRetryPolicyFactory, requestFactory, backOffPolicyFactory); } @Bean @ConditionalOnMissingBean public RestTemplateCustomizer restTemplateCustomizer( final RetryLoadBalancerInterceptor loadBalancerInterceptor) { return new RestTemplateCustomizer() { @Override public void customize(RestTemplate restTemplate) { List<ClientHttpRequestInterceptor> list = new ArrayList<>( restTemplate.getInterceptors()); list.add(loadBalancerInterceptor); restTemplate.setInterceptors(list); } }; } } }
这里面就用到了我们上面提到那几个条件注解,通过这个自动配置,我们就可以在spring boot项目里面引入@LoadBalanced注解来实现客户端的负载均衡。
相关文章推荐
- Spring Boot之自动配置的原理
- springboot学习----自动配置
- Spring boot中@Conditional和spring boot的自动配置实例详解
- 初识Spring Boot框架之Spring Boot的自动配置
- SpringBoot--AxonFramework自动配置
- 初识Spring Boot框架(二)之DIY一个Spring Boot的自动配置
- Spring Boot实战教程之自动配置详解
- 第5章 Spring Boot自动配置原理
- SpringBoot的WebSocket基于STOMP协议自动广播推送配置
- 一个由于springboot自动配置所产生的问题的解决
- Spring Boot核心原理-自动配置
- SpringBoot 自动配置
- 初识Spring Boot框架(二)之DIY一个Spring Boot的自动配置
- SpringBoot自动配置的简单分析
- spring boot自动配置幕后
- 如何编写Spring-Boot自动配置
- [Spring Boot] 4. Spring Boot实现自动配置的原理
- AxonFramework,SpringBoot自动配置
- 参照SpringBoot的自动配置
- spring-boot 是如何实现自动配置的