开发一个gp-spring-boot-starter
欢迎来到Java架构师试听课,开发者可以自定义说的人。
新建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
在其他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
官网见: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.
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的时候,就需要把上面过程重复一遍,测试通过后再使用,很麻烦!
包含所有jar包
比如需要使用jpa,starter能不能把所有的jar包依赖包含进来?如果可以,那把这个starter就定义为一个project。
配置值
这些jar包在原来的使用方式中肯定需要配置xml文件,这些属性的配置在该project中用一个ConfigurationProperties配置类来定义,并且提供给最终的使用者一个赋值方式application.properties。
类的使用
包含在AutoConfiguration中,并且给spring-boot项目扫描spring.factories文件。
创建一个项目表示starter,比如gp-spring-boot-starter
功能的实现,比如IGupao和GupaoImpl
ConfigurationProperties类保存配置信息,比如GupaoProperties
创建一个AutoConfiguration,引用定义好的配置信息,在其中完成starter应该进行的操作,比如GupaoAutoconfiguration
定义给spring-boot扫描的文件,比如spring.factories
打包项目,然后在其他spring-boot项目中使用
地址: https://github.com/spring-projects/spring-boot/tree/1.5.x/spring-boot-starters
地址: https://stackoverflow.com/questions/28273543/what-are-spring-boot-starter-jars/28273660#28273660
<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>
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
/**
* Server HTTP port.
*/
private Integer port;
......
}
@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);
}
......
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.boot.autoconfigure.EnableAutoConfiguration= org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
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();