starter的定义:为了把第三方集成到springboot中,并且把第三方工具的实例融入到ioc中,并且可以去支持外部自定义的配置(一般在application.properties中配置)。

       新建一个maven项目:

         

 

 

  一般官方的starter是spring-boot-starter-{name} 这种命名,而第三方建议是{name}-spring-boot-starter。这个starter主要是用了来对对象转为字符串与json串的。

写好基本的代码:

package com.llicat.processor;

/**
 * Copyright: Copyright (c) 2020
 *
 * @ClassName: com.llicat.processor.formatProcessor
 * @Description: 标准转换接口
 * @version: v1.0.0
 * @author: lipan
 * @date: 2020/11/29 20:44
 * <p>
 * Modification History:
 * Date         Author          Version            Description
 * ------------------------------------------------------------
 * 2020/11/29      lipan          v1.0.0               修改原因
 */

public interface FormatProcessor {

    /**
     * 对象转为代码
     * @param obj
     * @param <T>
     * @return
     */
    <T> String format(T obj);
}


package com.llicat.processor;

import com.alibaba.fastjson.JSON;

/**
 * Copyright: Copyright (c) 2020
 *
 * @ClassName: com.llicat.processor.JsonFormatProcessor
 * @Description: 该类的功能描述
 * @version: v1.0.0
 * @author: lipan
 * @date: 2020/11/29 20:47
 * <p>
 * Modification History:
 * Date         Author          Version            Description
 * ------------------------------------------------------------
 * 2020/11/29      lipan          v1.0.0               修改原因
 */

public class JsonFormatProcessor implements FormatProcessor {
    @Override
    public <T> String format(T obj) {
        return JSON.toJSONString(obj);
    }
}

package com.llicat.processor;

import java.util.Objects;

/**
 * Copyright: Copyright (c) 2020
 *
 * @ClassName: com.llicat.processor.StringFormatProcessor
 * @Description: 该类的功能描述
 * @version: v1.0.0
 * @author: lipan
 * @date: 2020/11/29 20:46
 * <p>
 * Modification History:
 * Date         Author          Version            Description
 * ------------------------------------------------------------
 * 2020/11/29      lipan          v1.0.0               修改原因
 */

public class StringFormatProcessor implements FormatProcessor {
    @Override
    public <T> String format(T obj) {
        return Objects.toString(obj);
    }
}

package com.llicat.template;

import com.llicat.processor.FormatProcessor;

/**
 * Copyright: Copyright (c) 2020
 *
 * @ClassName: com.llicat.template.FormatTemplate
 * @Description: 通用模板
 * @version: v1.0.0
 * @author: lipan
 * @date: 2020/11/29 20:49
 * <p>
 * Modification History:
 * Date         Author          Version            Description
 * ------------------------------------------------------------
 * 2020/11/29      lipan          v1.0.0               修改原因
 */

public class FormatTemplate {


    protected FormatProcessor  processor;

    public <T> String formatToString(T obj){
        return processor.format(obj);
    }

}

然后可以测试一下,install之后测试一下基本功能:

@SpringBootTest(classes=Application.class)
@RunWith(SpringRunner.class)
public class FormatStarterTest {


    @Test
    public void test() throws Exception{

        FormatProcessor processor=new JsonFormatProcessor();

        FormatTemplate template=new FormatTemplate(processor);
        Person person = new Person();
        person.setId(10);
        person.setName("小明");
        System.out.println(template.formatToString(person));
    }

}

输出结果:

 

 

 

但是这样会有一个问题:对象FormatProcessor 与FormatTemplate都是自己new出来的,这样就违背了spring自动装配的约定。所以需要定义配置类将这些东西装载到ioc中。

定义一个类将processor加载到ioc中:

@Configuration
public class ProcessorAutoConfig {



    //用来装配StringFormatProcessor到容器中
    @Bean
    public FormatProcessor  stringFormatProcessor(){
        return  new StringFormatProcessor();
    }


    @Bean
    public JsonFormatProcessor jsonFormatProcessor(){
       return  new JsonFormatProcessor();
    }

}

 将format加载到ioc中:

@Configuration
@SuppressWarnings("all")
@Import(ProcessorAutoConfig.class)
public class TemplateAutoConfig {

    @Bean
    public FormatTemplate formatTemplate(FormatProcessor formatProcessor){
        return new FormatTemplate(formatProcessor);
    }

}

 需要提一点的是通过@import将ProcessorAutoCofig中的也加载到了。修改一下测试代码:

@SpringBootTest(classes=Application.class)
@RunWith(SpringRunner.class)
public class FormatStarterTest {



    @Autowired
    FormatTemplate template;

    @Test
    public void test() throws Exception{


        Person person = new Person();
        person.setId(10);
        person.setName("小明");
        System.out.println(template.formatToString(person));
    }

}

运行后:

 

 因为找不到唯一匹配的实例。所以需要修改一下processor的加载代码:

@Configuration
public class ProcessorAutoConfig {



    //用来装配StringFormatProcessor到容器中
    @Bean
    @Primary
    public FormatProcessor  stringFormatProcessor(){
        return  new StringFormatProcessor();
    }


    @Bean
    public JsonFormatProcessor jsonFormatProcessor(){
       return  new JsonFormatProcessor();
    }

}

指定默认的就会返回stringFormatProcessor作为实例:

 

 我们也可以使用条件注解来指定就是是哪一个processor会被加载:

@Configuration
public class ProcessorAutoConfig {



    //用来装配StringFormatProcessor到容器中
    @Bean
    @Primary
    @ConditionalOnMissingClass("com.alibaba.fastjson.JSON")
    public FormatProcessor  stringFormatProcessor(){
        return  new StringFormatProcessor();
    }


    @Bean
    @ConditionalOnClass(name = "com.alibaba.fastjson.JSON")
    public JsonFormatProcessor jsonFormatProcessor(){
       return  new JsonFormatProcessor();
    }

}

这段代码指明了,当前环境如果加载了com.alibaba.fastjson.JSON ,那么就会在加载jsonFormatProcessor,否则加载默认的processor。我们在pom.xml中引入jack的依赖:

 

 此时是就是json对象的format在对对象进行解析了。

实际上在使用各种starter的时候我们还会自定义一些属性在application.properties如下:

 

 

,这些是由starter提供的,实际上也是可以自定义的:

@ConfigurationProperties(prefix = "com.llicat.format")
@SuppressWarnings("all")
public class FormatProperties {

    private String language;

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }
}

使用定义的属性:

public class FormatTemplate {


    protected FormatProperties properties;
    protected FormatProcessor  processor;


    public FormatTemplate(FormatProperties properties,FormatProcessor processor) {
        this.properties=properties;
        this.processor = processor;
    }

    public <T> String formatToString(T obj){
      if( "CN".equals(properties.getLanguage())){
          return "format result:"+processor.format(obj);

      }else{
          return "转换失败,请提供多语言资源包";
      }
    }

}

 需要增加配置文件:

 

 

 

spring 使用spi来加载第三方,所以这个必须要。

     使用自定义属性 :

 

 

 

 

 

 运行结果:

 

 

 tips:

resource下文件无法编译到target:

 

 

  把这个干掉。

maven打包resource打不进去增加这个配置:

    <resources>

            <!--用来解决install打包的时候resource下的配置文件打不进去-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>