转载

关于Spring Boot你不得不知道的事--Spring Boot Starter

Spring Boot Starter

1 自定义一个starter

1.1 需求

开发一个gp-spring-boot-starter

欢迎来到Java架构师试听课,开发者可以自定义说的人。

1.2 步骤

  • 新建maven工程

groupId:com.gupao

artifactId:gp-spring-boot-starter

  • pom文件配置

<!--spring boot中的parent-->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <!-- 自动化配置依赖,自定义 starter 核心依赖包 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
    </dependency>
</dependencies>
  • 新建接口IGupao和实现类GupaoImpl

public interface IGupao {
    void welcome();
}
public class GupaoImpl implements IGupao {
    @Autowired
    private GupaoProperties gupaoProperties;    //GupaoProperties可以对name进行赋值
    @Override
    public void welcome() {
        String name=gupaoProperties.getName();
        System.out.println(name+" : 欢迎来到咕泡学院Java架构师VIP试听课");
    }
}
  • 新建配置类GupaoProperties

@ConfigurationProperties(prefix = "spring.gupao")    //--->方便开发者在配置文件中对其进行赋值
public class GupaoProperties {
    private String name="Jack";
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
  • 创建自动配置类

//标记当前类为一个配置类,让Spring去扫描它
@Configuration
//条件注解,只有在classpath路径下存在指定class文件时,才会实例化 Bean
@ConditionalOnClass(Gupao.class)
//使指定配置类GupaoProperties生效
@EnableConfigurationProperties(GupaoProperties.class)
public class GupaoAutoConfiguration {
    //创建一个实例类注入到 Spring IOC容器中
    @Bean
    //条件注解,意思是,仅当 IOC容器不存在指定类型的Bean时,才会创建 Bean
    @ConditionalOnMissingBean
    public Gupao gupao() {
        return new GupaoImpl();
    }
}
  • 新建spring.factories文件

放到resources/META-INF/spring.factories

# Spring Boot会在启动时自动去查找指定文件 /META-INF/spring.factories
# 有的话,就会根据配置的类的全路径去自动化配置,指定刚刚创建的GupaoAutoConfiguration的全路径名
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.gupao.GupaoAutoConfiguration
  • 打包

在gp-spring-boot-starter根目录下执行:mvn clean install

1.3 使用

  • 在其他Spring Boot项目中引入上述starter

<dependency>
    <groupId>com.gupao</groupId>
    <artifactId>gp-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
  • XXXApplication

@SpringBootApplication
public class BootifulApplication implements CommandLineRunner {
    @Autowired
    private Gupao gupao;
    @Override
    public void run(String... args) throws Exception {
        gupao.welcome();
    }
}
  • application.properties

spring.gupao.name=AAA

2 理解starter

2.1 官网

官网见:13.5 Starters

Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and related technologies that you need without having to hunt through sample code and copy-paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, include the spring-boot-starter-data-jpa dependency in your project.

2.2 自我消化

  • spring-boot中使用

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
spring.jpa.database=
spring.jpa.generate-ddl=
  • 如果不用starter-jpa

(1)pom文件中引入mysql驱动依赖
(2)引入jpa依赖
(3)在xxx.xml文件中配置一些属性信息
(4)测试是否正常

conclusion: 以后每个项目中需要使用到jpa的时候,就需要把上面过程重复一遍,测试通过后再使用,很麻烦!

2.3 starter思想

  • 包含所有jar包

比如需要使用jpa,starter能不能把所有的jar包依赖包含进来?如果可以,那把这个starter就定义为一个project。

  • 配置值

这些jar包在原来的使用方式中肯定需要配置xml文件,这些属性的配置在该project中用一个ConfigurationProperties配置类来定义,并且提供给最终的使用者一个赋值方式application.properties。

  • 类的使用

包含在AutoConfiguration中,并且给spring-boot项目扫描spring.factories文件。

2.4 创建一个Spring Boot Starter

创建一个项目表示starter,比如gp-spring-boot-starter

功能的实现,比如IGupao和GupaoImpl

ConfigurationProperties类保存配置信息,比如GupaoProperties

创建一个AutoConfiguration,引用定义好的配置信息,在其中完成starter应该进行的操作,比如GupaoAutoconfiguration

定义给spring-boot扫描的文件,比如spring.factories

打包项目,然后在其他spring-boot项目中使用

2.5 官方提供的一些starters

地址: https://github.com/spring-projects/spring-boot/tree/1.5.x/spring-boot-starters

2.6 再次理解starters

地址: https://stackoverflow.com/questions/28273543/what-are-spring-boot-starter-jars/28273660#28273660

3 starter-tomcat实现

3.1 引入jar包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependencies>
  <dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>9.0.19</version>
    <scope>compile</scope>
    <exclusions>
      <exclusion>
        <artifactId>tomcat-annotations-api</artifactId>
        <groupId>org.apache.tomcat</groupId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-el</artifactId>
    <version>9.0.19</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-websocket</artifactId>
    <version>9.0.19</version>
    <scope>compile</scope>
  </dependency>
</dependencies>

3.2 Properties配置类

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {

   /**
    * Server HTTP port.
    */
   private Integer port;
   ......
}

3.3 AutoConfiguration

@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
      ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
      ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
      ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {

   @Bean
   public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(
         ServerProperties serverProperties) {
      return new ServletWebServerFactoryCustomizer(serverProperties);
   }
   ......
}

3.4 spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.boot.autoconfigure.EnableAutoConfiguration=
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration

3.5 内置tomcat调用

ServletWebServerFactoryConfiguration.EmbeddedTomcat.class
public TomcatServletWebServerFactory() {
}
public WebServer getWebServer(ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();
File baseDir = (this.baseDirectory != null) ? this.baseDirectory
      : createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
   tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatWebServer(tomcat);
}
  • 调用过程

SpringApplication.run(SpringbootDemo2Application.class, args);
...
refreshContext(context);
refresh(context);
((AbstractApplicationContext) applicationContext).refresh();
// Initialize other special beans in specific context subclasses.
onRefresh();
ServletWebServerApplicationContext.onRefresh();
createWebServer();
this.webServer = factory.getWebServer(getSelfInitializer());
TomcatServletWebServerFactory.getWebServer();
原文  http://mp.weixin.qq.com/s?__biz=MzUzODU4MjE2MQ==&mid=2247484052&idx=1&sn=85b1ec13d5b8a653e9732df3e012ed5b
正文到此结束
Loading...