SpringBoot2 编写自定义AutoConfig

什么是Spring AutoConfig

Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added. For example, if HSQLDB is on your classpath, and you have not manually configured any database connection beans, then Spring Boot auto-configures an in-memory database.
You need to opt-in to auto-configuration by adding the @EnableAutoConfiguration or @SpringBootApplication annotations to one of your @Configuration classes.
引用自: https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html

怎样编写SpringBoot2 AutoConfig

使用自动配置HttpClient作为例子.

编写一个属性配置类

@ConfigurationProperties(prefix = "spring.httpclient")
@Data
public class HttpClientProperties {
    private Integer connectTimeOut = 1000;
    private Integer socketTimeOut = 10000;
    private String agent = "agent";
    private Integer maxConnPerRoute = 10;
    private Integer maxConnTotal = 50;
}

@ConfigurationPropertiesprefix 提示Spring在启动时将配置文件中 spring.httpclient 的与本类属性相对应的属性自动加载进来.
@Data 是lombok的注解.

编写自动配置核心类

@Configuration
@ConditionalOnClass({HttpClient.class})
@EnableConfigurationProperties(HttpClientProperties.class)
public class HttpClientAutoConfiguration {

    private final HttpClientProperties properties;

    public HttpClientAutoConfiguration(HttpClientProperties properties) {
        this.properties = properties;
    }


    /**
     * httpclient bean的定义
     * @return Http Client
     *
     * ConditionalOnMissingBean -> 当用户未定义的时候才会创建
     */
    @Bean
    @ConditionalOnMissingBean(HttpClient.class)
    public HttpClient httpClient() {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(properties.getConnectTimeOut())
                .setSocketTimeout(properties.getSocketTimeOut())
                .build();
        return HttpClientBuilder.create()
                .setDefaultRequestConfig(requestConfig)
                .setUserAgent(properties.getAgent())
                .setMaxConnPerRoute(properties.getMaxConnPerRoute())
                .setMaxConnTotal(properties.getMaxConnTotal())
                // 防止重试
                .setConnectionReuseStrategy(new NoConnectionReuseStrategy())
                .build();
    }
}
  • @Configuration: 将本类标识为SpringBoot的Java配置类
  • @ConditionalOnClass({HttpClient.class}): 只有在HttpClient.class存在时才会加载java config
  • @EnableConfigurationProperties(HttpClientProperties.class):本类加载时注入 HttpClientProperties 属性配置的bean
  • httpClient()的@ConditionalOnMissingBean(HttpClient.class):只有当没有创建HttpClient bean的时候,才会执行 httpClient()方法创建一个HttpClient bean

使Spring感知自动配置类.

spring-boot-autoconfigureMETA-INF/spring.factories 中, 编写了非常多的开源软件的自动配置类. 而如果我们自己编写自动配置类. 有以下几种方式:

方式一

autoconfig在本项目的 @SpringBootApplication 目录下,不需要其他配置, 可以直接通过 @AutoWired 注入 HttpClient,如:
···
@RunWith(SpringRunner.class)
@SpringBootTest
public class HouseApplicationTests {

@Autowired
private HttpClient httpClient;

@Test
public void contextLoads() throws IOException {
	String toString = httpClient.execute(new HttpGet("http://www.imyzt.top")).getEntity().toString();
	System.out.println(toString);
}

}
···

方式二

autoconfig不在本项目的 @SpringBootApplication 目录下,可以有两种方式自动配置:

  1. 在本项目的resources下编写 META-INF/spring.factories 文件.
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
top1.imyzt.autoconfig.HttpClientAutoConfiguration
  1. [推荐] 编写 @EnableHttpClient
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(HttpClientAutoConfiguration.class)
public @interface EnableHttpClient {
}

在启动类上加上注解, 即可开启HttpClient配置.

总结

教程是在学习慕课网上的 Java从单体到微服务打造房产销售平台 时学习到的, 在此博客做一个总结, 以便后面复习.

上述代码在我的 Github 上可以找到.