浅谈:Spring Boot原理分析(更多细节解释在代码注释中)
通过@EnableAutoConfiguration注解加载Springboot内置的自动初始化类(加载什么类是配置在spring.factories),这这些类中在基于spring4.0提供的Condition接口进行Bean的初始化。
Condition
⚫ 自定义条件:
① 定义条件类:自定义类实现Condition接口,重写 matches 方法,在 matches 方法中进行逻辑判断,返回
boolean值 。 matches 方法两个参数:
• context:上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等。
• metadata:元数据对象,用于获取注解属性。
② 判断条件: 在初始化Bean时,使用 @Conditional(条件类.class)注解
⚫ SpringBoot 提供的常用条件注解:
• ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean
• ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean
• ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean
案列说明Condition
首先搭建springboot的项目
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 导入springboot父工程spring-boot-starter-parent,
我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fs</groupId>
<artifactId>springboot-condition</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- 引入starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 引入redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>
自定义注解
MyCondition
package com.fs.condition;
import org.springframework.context.annotation.Conditional;
import java.lang.annotation.*;
/*
自定义注解
*/
//元注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
//判断条件: 在初始化Bean时,使用 @Conditional(条件类.class)注解
@Conditional(ClassCondition.class)
public @interface MyCondition {
String[] value();
}
自定义定义条件类:自定义类实现Condition接口,重写 matches 方法,在 matches 方法中进行逻辑判断,返回boolean值 。 matches 方法两个参数:
• context:上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等。
• metadata:元数据对象,用于获取注解属性。
判断条件: 在初始化Bean时,使用 @Conditional(条件类.class)注解
package com.fs.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import java.util.Map;
/*
springboot的底层实现原理是什么?
基于spring4.0提供的Condition接口进行实现
*/
//创建一个自定义类来实现org.springframework.context.annotation.Condition;接口
public class ClassCondition implements Condition {
/**
* @param conditionContext conditionContext上下文,共享数据的,用于获取环境,IOC容器,ClassLoader对象
* @param annotatedTypeMetadata 注解元数据,拿到Conditional注解的元数据,可以用于获取注解定义的属性值
* @return 返回布尔,确定加上@Conditional(ClassCondition.class)后这个bean是否创建
*/
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//返回的布尔就表示spring是否创建对应的bean
//可以根据条件判断是否创建bean
//return false;
//可以按照Class.forName(类全路径包名)来判断是否导入这个类的依耐是否导入,导入就创建
//获取我们注解属性值
Map<String, Object> map = annotatedTypeMetadata.getAnnotationAttributes(MyCondition.class.getName());
String[] values = (String[])map.get("value");
boolean flag = true;
try {
for (String className : values) {
Class<?> cls = Class.forName(className);
}
} catch (ClassNotFoundException e) {
flag = false;
}
return flag;
}
}
在配置类中使用
package com.fs.config;
import com.fs.condition.ClassCondition;
import com.fs.condition.MyCondition;
import com.fs.pojo.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserConfig {
// @Bean
// //指定一个自定义类实现Condition接口是否spring创建这bean
// @Conditional(ClassCondition.class)
// public User user(){
// return new User();
// }
//使用自定义的Condition注解
@Bean
//使用自定义的注解
@MyCondition("com.fs.pojo.User")
public User user2(){
return new User();
}
//指定application配置文件有这个属性就加载bean
@Bean
@ConditionalOnProperty(name = "xiaofu",havingValue = "haha")
public User user3(){
return new User();
}
}
application.yml
由于我们配置类中使用了@ConditionalOnProperty(name = “xiaofu”,havingValue = “haha”)
所以需要在application配置文件中编写配置,才会让配置类中的bean初始化
# 设置属性,让user3初始化
xiaofu: haha
主启动测试
package com.fs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
/**
* @ComponentScan() 扫描引导类所在包及其子包
*/
@SpringBootApplication
public class SpringBootCondition {
public static void main(String[] args) {
//启动springboot的应用,返回spring的IOC容器
ConfigurableApplicationContext context = SpringApplication.run(SpringBootCondition.class, args);
/*
SpringBoot是如何知道要创建哪个Bean的?比如SpringBoot是如何知道要创建RedisTemplate的?
因为我们在maven引入了spring-boot-starter-data-redis这个依耐,就会根据@Conditional注解去判断是否初始化这个bean
*/
//获取bean,获取redisTemplate
Object redisTemplate = context.getBean("redisTemplate");
System.out.println(redisTemplate);
//我们自定义了配置类,UserConfig 类中的方法也加上了@Condition注解来判断是否注入这个
Object user2 = context.getBean("user2");
System.out.println(user2);
//使用springboot提供的注解来判断是否初始化bean
Object user3 = context.getBean("user3");
System.out.println(user3);
}
}
说明我们自定义的Condition 条件判断没有问题
切换内置web服务器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--排除tomcat依赖-->
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--引入jetty的依赖-->
<dependency>
<artifactId>spring-boot-starter-jetty</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>
如何自定义Stater?(@Import 自定义Enable注解 spring.factories 等)
@Enable*注解
SpringBoot中提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的。而其底层原理是使用@Import注解导入一些配置类,实现Bean的动态加载。
@Import注解
@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@Import提供4中用法:
① 导入Bean
② 导入配置类 @Import(spring配置类.class)
③ 导入 ImportSelector 实现类。一般用于加载配置文件中的类
④ 导入 ImportBeanDefinitionRegistrar 实现类。
@EnableAutoConfiguration 注解
⚫ @EnableAutoConfiguration 注解内部使用 @Import(AutoConfigurationImportSelector.class)来加载配置类。
⚫ 配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当 SpringBoot 应用启动时,会自动加载这些配置类,初始化Bean
⚫ 并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean
实现步骤
① 创建 redis-spring-boot-autoconfigure 模块
② 创建 redis-spring-boot-starter 模块,依赖 redis-springboot-autoconfigure的模块
③ 在 redis-spring-boot-autoconfigure 模块中初始化 Jedis 的
Bean。并定义META-INF/spring.factories 文件
④ 在测试模块中引入自定义的 redis-starter 依赖,测试获取
Jedis 的Bean,操作 redis。
① 创建 redis-spring-boot-autoconfigure 模块
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 导入springboot父工程spring-boot-starter-parent,
我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fs</groupId>
<artifactId>redis-spring-boot-autoconfigure</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--引入jedis依赖-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>
</project>
RedisAutoConfiguration 自定义的AutoConfiguration类
package com.fs.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;
/*
自定义的AutoConfiguration类
*/
@Configuration
//这个注解会去找我们给的的Class.class,并且这个类要被@ConfigurationProperties注解标记
//说白了 @EnableConfigurationProperties 相当于把使用 @ConfigurationProperties 的类进行了一次注入。
@EnableConfigurationProperties(RedisProperties.class)
//这个注解表示判断环境中是否有对应字节码文件才初始化Bean,判断是否导入了Jedis的包,当前项目环境中有没有Jedis这个类
//有才会去初始化我们当前类下方法的bean
@ConditionalOnClass(Jedis.class)
public class RedisAutoConfiguration {
@Bean
//这个Condition注解的意思就是判断环境中没有对应Bean才初始化Bean,
//IOC容器中有么有名为jedis的bean,有就不初始化我们这个bean
@ConditionalOnMissingBean(name="jedis")
public Jedis jedis(RedisProperties redisProperties){
//初始化bean,并将我们的属性类中的值给这个bean
return new Jedis(redisProperties.getHost(),redisProperties.getPort());
}
}
RedisProperties 自定义的简陋的redis连接属性类
package com.fs.config;
/*
自定义的简陋的redis连接属性类
*/
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
//docker start -i 容器名称
@Component
//ConfigurationProperties这个注解就会去application.yml中去找对应的一组属性值,并赋值给我们自定义的属性类的成员变量
@ConfigurationProperties(prefix = "xiaofu.redis")
public class RedisProperties {
//提供2个属性,从application配置文件中去读取.指定默认指,用户不在application中配置,就使用默认的
private String host = "localhost";
private Integer port = 6379;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
}
User 实体类,用于测试自定义@Enable注解使用
package com.fs.pojo;
public class User {
}
UserConfig User配置类,注入User Bean
package com.fs.config;
import com.fs.pojo.User;
import org.springframework.context.annotation.Bean;
public class UserConfig {
@Bean
public User user(){
return new User();
}
}
EnableAutoUser 自定义Enable注解
package com.fs.enable;
import com.fs.config.UserConfig;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
//元注解信息
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//自定义注解,当加上这个注解,就会自动将配置类中的bean注入到IOC容器中
@Import(UserConfig.class)
public @interface EnableAutoUser {
}
spring.factories 自定义starter核心的配置文件
# 这个配置文件一定要在resources/META-INF/spring.factories下
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.fs.config.RedisAutoConfiguration
② 创建 redis-spring-boot-starter 模块,依赖 redis-springboot-autoconfigure的模块
创建starter工程(遵循Spring starter命名规范)
pom.xml 主要引入我们自定义的 redis-springboot-autoconfigure
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 导入springboot父工程spring-boot-starter-parent,
我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fs</groupId>
<artifactId>redis-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--引入自定义的redis-configure-->
<dependency>
<groupId>com.fs</groupId>
<artifactId>redis-spring-boot-autoconfigure</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
创建springboot工程测试我们自定义的starter 模块
pom.xml 引入我们自定义的 redis-spring-boot-starter 模块
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 导入springboot父工程spring-boot-starter-parent,
我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fs</groupId>
<artifactId>test-Redis-restart</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- 引入自定义的restart-->
<dependency>
<groupId>com.fs</groupId>
<artifactId>redis-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
application.yml
# 使用我们自定义的autoconfigure 的RedisProperties 属性类@ConfigurationProperties(prefix = "xiaofu.redis")
xiaofu:
redis:
host: 47.112.174.148
port: 6379
主启动 MyStarterApp
package com.fs;
import com.fs.enable.EnableAutoUser;
import com.fs.pojo.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import redis.clients.jedis.Jedis;
@SpringBootApplication
//使用自定义的注解,就会自动加载自定义注解上@Import(UserConfig.class)的配置类,注入bean
@EnableAutoUser
public class MyStarterApp {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(MyStarterApp.class, args);
//从容器中获取我们自定义的Jedis,
//由于@SpringBootApplication注解中的@EnableAutoConfiguration
//会自动去加载META-INF/spring.factories,该配置文件中定义了大量的配置类
//我们自定义的redis-spring-boot-autoconfigure项目也写了一个spring.factories,所以就会把我们自定义的RedisAutoConfiguration配置类加载初始化bean
Jedis bean = context.getBean(Jedis.class);
System.out.println(bean);
//由于我们配置文件中指定了host地址,测试一下
bean.set("haha","xixi");
String haha = bean.get("haha");
System.out.println(haha);
//获取user
User user = context.getBean(User.class);
System.out.println(user);
}
}
测试结果
SpringBoot 监控概述
SpringBoot自带监控功能Actuator,可以帮助实现对程序内部运行情况监控,比如监控状况、Bean加载情况、配置属性、日志信息等。
SpringBoot 监控使用
① 导入依赖坐标
org.springframework.boot
spring-boot-starter-actuator
② 访问http://localhost:8080/acruator
SpringBoot 监控 - Spring Boot Admin
SpringBoot 监控 - Spring Boot Admin
⚫ Spring Boot Admin是一个开源社区项目,用于管理和监控SpringBoot应用程序。
⚫ Spring Boot Admin 有两个角色,客户端(Client)和服务端(Server)。
⚫ 应用程序作为Spring Boot Admin Client向为Spring Boot Admin Server注册
⚫ Spring Boot Admin Server 的UI界面将Spring Boot Admin Client的Actuator Endpoint上的一些监控信息。
使用步骤
admin-server:
① 创建 admin-server 模块
② 导入依赖坐标 admin-starter-server
③ 在引导类上启用监控功能@EnableAdminServer
admin-client:
① 创建 admin-client 模块
② 导入依赖坐标 admin-starter-client
③ 配置相关信息:server地址等
④ 启动server和client服务,访问server
Spring Boot Admin 项目搭建
springboot-admin-service
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 导入springboot父工程spring-boot-starter-parent,
我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fs</groupId>
<artifactId>springboot-admin-service</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
server:
port: 9000
主启动 SpringbootAdminService
package com.fs;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//开启adminserver
@EnableAdminServer
@SpringBootApplication
public class SpringbootAdminService {
public static void main(String[] args) {
SpringApplication.run(SpringbootAdminService.class,args);
}
}
springboot-admin-client
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 导入springboot父工程spring-boot-starter-parent,
我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fs</groupId>
<artifactId>springboot-admin-client</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-client -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
boot:
admin:
client:
url: http://127.0.0.1:9000 # 注意这里必须写ip 指定adminserver的地址
application:
name: xiaofu-springboot
management:
endpoint:
health:
show-details: always
endpoints:
web:
exposure:
include: "*" # 将所有的监控endpoint暴露出来
主启动 SpringbootAdminClient
package com.fs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootAdminClient {
public static void main(String[] args) {
SpringApplication.run(SpringbootAdminClient.class,args);
}
}
controller
package com.fs.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/hello")
public class TestController {
@RequestMapping("/world")
public String add(){
return "HelloWorld";
}
}
启动两个项目,打开浏览器测试
就可以一目了然啦
springboot的项目打成war包
==1 改造启动类 ==
package com.fs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/*
将springboot的项目打成war包
1.先在pom文件中设置war
2.将主启动类extends SpringBootServletInitializer
3.重写SpringApplicationBuilder configure(SpringApplicationBuilder builder){}方法
4.在configure方法中返回builder.sources(主启动.class);
*/
@SpringBootApplication
public class HelloWorld extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(HelloWorld.class,args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(HelloWorld.class);
}
}
2 改造POM.xml
<packaging>war</packaging>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 导入springboot父工程spring-boot-starter-parent,
我们自己的的helloworld就成为springboot的子工程会自动引入父工程的依耐-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fs</groupId>
<artifactId>springboot-HelloWorld</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 将springboot项目打成war包-->
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 引入web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<!-- 给war包起个名字-->
<finalName>HelloWorld</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
点名maven的package就能得到war包的springboot项目啦