SpringBoot学习系列(十二)------自定义starters

SpringBoot学习系列(十二)------自定义starters

前言

SpringBoot的使用方便了我们的开发,究其原因,还是因为我们使用了很多的的starters,在我们导入这些starters的依赖以后,SpringBoot会帮我们注入很多的自动配置,在这里,我们可以来研究一下starters,实现自己的starters.

正文

1. WebMvcAutoConfiguration

我们查看这个类,可以发现有几个需要注意的注解:

@Configuration	//指定这个类是一个配置类
@ConditionalOnWebApplication	//所有已ConditionalOnXXX开头的,都是在满足该条件的情况下,配置才生效
@AutoConfigureAfter	//指定自动配置类的顺序
@Bean	//给容器中添加组件
@ConfigurationProperties	//根据相关的Properties属性类来绑定相关的配置
@EnableConfigurationProperties //让Properties生效,并加入容器中

//要想在启动的时候自动配置类能被加载,还必须要将配置类放在META/INF/spring.factories中指定
//如下指定:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\

2. SpringBoot默认的starters的模式

  • 启动器用来做依赖导入
  • 额外写一个自动配置的模块
  • 启动器依赖自动配置模块,在使用的时候只需要引入启动器(starter)即可

3. 实现自定义启动器

  • 创建一个空的工程模块,工程名为:spring-boot-starter

  • 在该工程下创建2个模块,一个作为启动器,一个作为自动配置模块:

    SpringBoot学习系列(十二)------自定义starters_第1张图片

    SpringBoot学习系列(十二)------自定义starters_第2张图片

    SpringBoot学习系列(十二)------自定义starters_第3张图片

    SpringBoot学习系列(十二)------自定义starters_第4张图片

    SpringBoot学习系列(十二)------自定义starters_第5张图片

    SpringBoot学习系列(十二)------自定义starters_第6张图片

    SpringBoot学习系列(十二)------自定义starters_第7张图片

  • 我们在starter中引入starter-autoconfigurer:

        
        <dependencies>
            <dependency>
                <groupId>com.xiaojian.startergroupId>
                <artifactId>xiaojian-spring-boot-starter-autoconfigurerartifactId>
                <version>0.0.1-SNAPSHOTversion>
            dependency>
        dependencies>
    
  • 创建一个绑定配置文件属性的配置类,用@ConfigurationProperties来标注:

    package com.xiaojian.starter;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    /**
     * ConfigurationProperties注解表示将配置文件中前缀为xiaojian.hello的属性绑定到该类的属性中
     */
    @ConfigurationProperties(prefix = "xiaojian.hello")
    public class HelloProperties {
    
        private String prefix;
    
        private String suffix;
    
        public String getPrefix() {
            return prefix;
        }
    
        public void setPrefix(String prefix) {
            this.prefix = prefix;
        }
    
        public String getSuffix() {
            return suffix;
        }
    
        public void setSuffix(String suffix) {
            this.suffix = suffix;
        }
    }
    
    
  • 接着我们定义一个service作为自动配置后主动执行的组件,在这个service中我们可以加入上一步中定义的HelloProperties,要注意,要想这个helloProperties被别的模块使用,需要加入get/set方法:

    package com.xiaojian.starter;
    
    public class HelloService {
    
        HelloProperties helloProperties;
    
        public HelloProperties getHelloProperties() {
            return helloProperties;
        }
    
        public void setHelloProperties(HelloProperties helloProperties) {
            this.helloProperties = helloProperties;
        }
    
        public String sayHello(String name) {
            return helloProperties.getPrefix() + "-"
                    + name + "-" + helloProperties.getSuffix();
        }
    }
    //这样,我们在调用sayHello方法的时候,会根绝配置文件中配置的前缀和后缀2个属性,加上我们传入的name,返回给调用者
    
  • 编写自动配置类:

    package com.xiaojian.starter;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * helloservice组件的自动配置类
     */
    @Configuration  //指定这是一个配置类
    @ConditionalOnWebApplication    //指定只有是web应用时,改配置才生效
    @EnableConfigurationProperties(HelloProperties.class)   //激活和属性文件绑定的类
    public class HelloServiceAutoConfiguration {
    
        @Autowired
        HelloProperties helloProperties;
    
        @Bean
        public HelloService helloService() {
            HelloService helloService = new HelloService();
            //在这里要把配置文件中的properties类设置到service中
            helloService.setHelloProperties(helloProperties);
            return helloService;
        }
    
    }
    
  • 要在classpath下创建一个META-INF文件夹,并在该文件夹下创建文件spring.factories,在文件中指定自定义自动配置类的全路径:

    SpringBoot学习系列(十二)------自定义starters_第8张图片

至此,我们自定义的starter全部完成,我们一起来看一下我们做了什么:

  1. 我们编写了一个自动配置类HelloServiceAutoConfiguration,注解@Configuration指定了它是一个配置类,注解@ConditionalOnWebApplication限定它只有在web环境中生效,注解@EnableConfigurationProperties(HelloProperties.class)标注它在启用时,会激活属性类HelloProperties,并且绑定到自身.
  2. HelloServiceAutoConfiguration中我们注入了一个bean,并将配置文件中以xiaojian.hello开头的属性类设置到helloservice中.
  3. spring.factories中,我们将HelloServiceAutoConfiguration配置进去,这样在启动的时候,我们自定义的自动配置类就能加载了.

4. 测试自定的starter

在前面我们自定义好了自己的starter,现在我们可以来创建一个工程测试一下:

SpringBoot学习系列(十二)------自定义starters_第9张图片

SpringBoot学习系列(十二)------自定义starters_第10张图片

我们创建好工程以后,在pom.xml文件中引入我们自定义的模块:

        
        <dependency>
            <groupId>com.xiaojiangroupId>
            <artifactId>xiaojian-spring-boot-starterartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>

在工程中编写一个测试的controller:

@RestController
public class HelloController {

    @Autowired
    private HelloService helloService;

    @GetMapping("/hello")
    public String hello(){
        return helloService.sayHello("张三");
    }
}

在该工程的配置文件中定义前缀和后缀:

xiaojian.hello.prefix=亲爱的
xiaojian.hello.suffix=你好

现在我们访问http://localhost:8080/hello来测试:

SpringBoot学习系列(十二)------自定义starters_第11张图片

可以看到我们自定义的配置起作用了.

总结

自定义自动配置模块,能帮助我们理解SpringBoot的starter实现过程,在技术的学习上,我们不仅要会用,也要对每一门技术的由来和原理有一定的认识.

你可能感兴趣的:(后端技术,SpringBoot)