开发一个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();