SpringBoot知识点
SpringBoot知识点
- SpringBoot知识点
- 1 SpringBoot 整合Redis
- 2 SpringBoot 整合Mybatis
- 3 自动配置Condition注解
- 4 切换内置web服务器方法
- 5 Enable注解原理
- 6 @Import 注解
- 7 @EnableAutoConfiguration 注解
- 8 自定义Starter方法
- 9 事件监听
- 10 流程分析
- 11 SpringBoot监控 actuator
- 12 SpringBoot admin图形化界面
- 13 SpringBoot部署
1 SpringBoot 整合Redis
1.1 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
1.2 resource 的 application.yml配置文件
spring:
application:
name: johnson
redis:
host: 192.168.1.128
port: 6379
server:
port: 8080
1.3 domain 创建一个Student实体
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student implements Serializable {
private static final long serialVersionUID = 3906599436996067748L;
private Integer id;
private String name;
private Integer age;
}
1.4 controller 创建RedisController 控制层,便于调试
@RestController
@RequestMapping("/redis")
public class RedisController {
@Resource
private RedisTemplate redisTemplate;
@Resource
private StringRedisTemplate stringRedisTemplate;
@PostMapping("/addstring")
public String addToRedis(String name,String value){
//操作Redis中String类型的数据,先获取ValueOperation
ValueOperations valueOperations = redisTemplate.opsForValue();
//添加数据到redis中
valueOperations.set(name,value);
return "向redis中添加string类型到数据";
}
@GetMapping("/getkey")
public String getData(String key){
ValueOperations valueOperations = redisTemplate.opsForValue();
Object s = valueOperations.get(key);
return "key是:"+key+" value是:"+s;
}
//使用StringRedisTemplate对象
@PostMapping("/{k}/{v}")
public String addToRedisString(@PathVariable String k,@PathVariable String v){
stringRedisTemplate.opsForValue().set(k, v);
return "向redis中添加string类型到数据";
}
@GetMapping("/{k}")
public String getData1(@PathVariable("k") String key){
String s = stringRedisTemplate.opsForValue().get(key);
return "key是:"+key+" value是:"+s;
}
//序列化操作
@PostMapping("/addjson")
public String addJson(){
//实例化一个学生对象
Student s1 = new Student(1, "周泽强", 18);
// 设置key 为string的序列化方式
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 设置value为json的序列化方式,json为 Student类型的方式组织,需要传入 Student.class
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Student.class));
redisTemplate.opsForValue().set("myStudent",s1);
return "存入json类型的student 成功";
}
@GetMapping("/getjson/{key}")
public String getJson(@PathVariable String key){
Student s = (Student) redisTemplate.opsForValue().get(key);
return s.toString();
}
}
2 SpringBoot 整合Mybatis
2.1 引入依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2.2 resource 的 application.yml配置文件
spring:
datasource:
url: jdbc:mysql://192.168.1.128:3306/mybatis
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
#使用xml方式 引入mapper文件位置
mybatis:
mapper-locations: classpath:mapper/*.xml
2.3 domain 创建一个Student实体
@Data
public class Student {
private Integer id;
private String name;
private Integer score;
private Integer age;
private Integer gender;
}
2.4 mapper 创建一个StudentMapper --注解形式
@Mapper
public interface StudentMapper {
@Select("select * from student")
List<Student> findAll();
}
2.5 mapper 创建一个StudentMapper1 --xml形式
@Mapper
public interface StudentMapper1 {
List<Student> findAll();
}
2.6 xml形式的 mapper
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.StudentMapper1">
<select id="findAll" resultType="com.example.demo.entity.Student">
select * from student
</select>
<!--定义接口方法对应的 SQL 语句-->
</mapper>
3 自动配置Condition注解
3.1 引入pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
3.2 获取依赖包中bean的方法
在 主程序中启动SpringBoot 应用,获得Spring返回的IOC容器
// 启动SpringBoot应用,返回Spring的IOC容器
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
// 获取bean,redisTemplate
Object redisTemplate = context.getBean("redisTemplate");
System.out.println(redisTemplate);
3.3 自定义bean获取方法
3.3.1 定义一个实体 User
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
private Integer id;
private String name;
private Integer age;
}
3.3.2 定义一个配置类
@Configuration
public class UserConfig {
@Bean
public User user(){
return new User(1,"johnson",2);
}
3.3.3 main中获取bean
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
// 自定义配置bean
Object user = context.getBean("user");
System.out.println(user);
3.4 @Conditional 条件方式获取bean
创建一个条件类,实现 Condition的接口,接口中有 matches方法返回布尔类型,如果为true加载到 spring容器中,如果为false 不加载
3.4.1 定义一个条件类实现 Condition接口
比如判断 Jedis有没有引入
public class ClassCondition implements Condition {
/**
*
* @param context 上下文对象,用于获取环境,IOC容器,ClassLoader对象
* @param metadata 注解元对象,可以用于获取注解属性值
* @return
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 1 导入jedis坐标后创建bean
boolean flag=true;
try {
Class.forName("redis.clients.jedis.Jedis");
} catch (ClassNotFoundException e) {
e.printStackTrace();
flag=false;
}
return flag;
}
3.4.2 在UserConfig 配置类中创建 bean
@Configuration
public class UserConfig {
@Bean
@Conditional(ClassCondition.class)
public User user2(){
return new User(1,"marry",2);
}
3.4.3 在启动main中获取bean
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Object user2 = context.getBean("user2");
System.out.println(user2);
3.5 自定义 ConditionOnClass
3.5.1 定义一个注解 ConditionOnClass
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 加入注解@Conditional ,加载 ClassCondition类
@Conditional(ClassCondition.class)
public @interface ConditionOnClass {
String[] value();
}
3.5.2 优化之前的ClassCondition类
public class ClassCondition implements Condition {
/**
*
* @param context 上下文对象,用于获取环境,IOC容器,ClassLoader对象
* @param metadata 注解元对象,可以用于获取注解属性值
* @return
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 2 导入通过注解属性值value指定坐标后创建bean
Map<String, Object> attributes = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
System.out.println(attributes);
String[] values = (String[]) attributes.get("value");
boolean flag = true;
for (String className : values) {
try {
Class<?> aClass = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
flag=false;
}
}
return flag;
}
}
3.5.3 配置类中调用 自定义的 ConditionOnClass注解
@Bean
@ConditionOnClass("redis.clients.jedis.Jedis")
public User user3(){
return new User(1,"marry",2);
}
3.5.4 主程序中获取bean
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Object user3 = context.getBean("user3");
System.out.println(user3);
3.6 常用的condition注解使用
@ConditionalOnProperty
3.6.1 在UserConfig中配置
@Bean
// 判断配置文件中是否有对应的属性值
@ConditionalOnProperty(value = "john",havingValue = "son")
public User user4(){
return new User();
}
3.6.2 在 application.yml 中
john=son1
3.6.3 在主程序中运行
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Object user4 = context.getBean("user4");
System.out.println(user4);
4 切换内置web服务器方法
4.1 直接在 pom中 exclusions 进行排除
<dependencies>
<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>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
</dependencies>
5 Enable注解原理
SpringBoot 中提供了很多 Enable开头的注解,这些注解是为了动态启动某些功能,其底层原理是使用@Import注解导入配置类,实现Bean的动态加载
6 @Import 注解
使用@Import 加载Bean有4种方法,可直接看
https://blog.csdn.net/mamamalululu00000000/article/details/86711079
或者
6.1 导入bean
6.1.1 在非本包路径下创建一个Entity的 User 和Role类
public class User {
}
public class Role {
}
6.1.2 本包路径主程序下 导入 实体bean
@Import(User.class)
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Object user = context.getBean("user");
System.out.println(user);
6.2 导入配置类
6.2.1 在非本包下创建一个配置类
@Configuration
public class UserConfig {
@Bean
public User user(){
return new User();
}
}
6.2.2 在本包主程序下运行
@Import(UserConfig.class)
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Object user = context.getBean("user");
System.out.println(user);
6.3 导入ImportSelector 实现类
6.3.1 在非本包下创建一个ImportSelector 实现类 SelfImportSelector
public class SelfImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.test.demo.entity.User","com.test.demo.entity.Role"};
}
}
6.3.2 在本包主程序下运行
@Import(SelfImportSelector.class)
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Object user = context.getBean("user");
System.out.println(user);
6.4 导入ImportBeanDefinitionRegister实现类
6.4.1 在非本包下创建一个 ImportBeanDefinitionRegister 实现类 SelfImportBeanDefinitionRegister
public class SelfImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
registry.registerBeanDefinition("user",new RootBeanDefinition(User.class));
}
}
6.4.2 在本包主程序下运行
@Import(SelfImportBeanDefinitionRegister.class)
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Object user = context.getBean("user");
System.out.println(user);
7 @EnableAutoConfiguration 注解
@EnableAutoConfiguration 注解内部使用了 @Import(AutoConfigurationImportSelector.class) 来加载配置类
配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当SpringBoot启动应用时,会加载配置类,初始化bean
并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的bean
8 自定义Starter方法
8.1 创建 redis-spring-boot-autoconfigure 模块
8.1.1 引入依赖 pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.3.0</version>
</dependency>
8.1.2 创建读取配置的类 RedisPropertis
@ConfigurationProperties(prefix = "redis")
public class RedisPropertis {
//设置默认host 为本地地址
private String host="localhost";
//设置默认port 为 6379
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;
}
}
8.1.3 创建一个自动配置类
// 定一个配置类
@Configuration
// 加载读取配置的bean
@EnableConfigurationProperties(RedisPropertis.class)
// 按条件加载,如果Jedis存在
@ConditionalOnClass(Jedis.class)
public class RedisAutoConfiguration {
// 将方法注入bean
@Bean
// 按条件加载,如果存在一个redis方法在bean中,则忽略此处的bean加载
@ConditionalOnMissingBean(name="redis")
public Jedis redis(RedisPropertis redisPropertis){
return new Jedis(redisPropertis.getHost(),redisPropertis.getPort());
}
}
8.1.4 在resource中 创建 META-INF/spring.factories
META-INF/spring.factories 为固定格式
org.springframework.boot.autoconfigure.EnableAutoConfiguration:能自动读取配置文件的包路径
com.test.config.RedisAutoConfiguration: 自定义的自动加载配置的路径
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.test.config.RedisAutoConfiguration
8.2 创建 redis-spring-boot-starter 模块,依赖 redis-spring-boot-autoconfigure的模块
8.2.1 引入依赖 pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>com.test</groupId>
<artifactId>redis-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
8.3 在测试模块中引入自定义的 redis-starter 依赖,测试获取 Jedis 的Bean,操作 redis。
8.3.1 引入依赖 pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>com.test</groupId>
<artifactId>redis-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
8.3.2 配置application.yml中的 host、port
# 应用名称
spring.application.name=test
redis.host=192.168.1.128
redis.port=6379
8.3.3 主程序中测试
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(TestApplication.class, args);
Jedis redis = context.getBean(Jedis.class);
System.out.println(redis);
redis.set("sex","very");
String s = redis.get("sex");
System.out.println(s);
}
}
9 事件监听
SpringBoot监听机制,其实是对Java提供的事件监听机制的封装
Java中的事件监听机制定义了以下几个角色
- 事件:Event,继承 java.util.EventObject类的对象
- 事件源:Source,任意对象 Object
- 监听器材: Listener,实现 java.util.EventLister接口的对象
SpringBoot在项目启动时,会对几个监听器进行回调,我么可以实现这些监听器接口,在项目启动时完成一些操作
会有如下几个:
- ApplicationContextInitializer
- SpringApplicationRunListener
- CommandLineRunner
- ApplicationRunner
9.1 ApplicationContextInitializer 示例
9.1.1 创建ApplicationContextInitializer 实现类
// spring ioc还未开始时检测资源是否存在
@Component
public class MyApplicationContextInitializer implements ApplicationContextInitializer {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
System.out.println("ApplicationContextInitializer....initialize");
}
}
- 如果没有创建对应的启动初始化配置,ApplicationContextInitializer实现类不会加载
- 所以需要创建 spring-factories
9.1.2 META_INF/spring-factories
org.springframework.context.ApplicationContextInitializer=com.example.demo.listener.MyApplicationContextInitializer
运行后即可看到对应的ApplicationContextInitializer 实现类被加载
9.2 SpringApplicationRunListener 示例
9.2.1 SpringApplicationRunListener 实现类
//@Component
public class MySpringApplicationRunListener implements SpringApplicationRunListener {
//必须要创建该构造方法
// 否则 //Caused by: java.lang.NoSuchMethodException: com.example.demo.listener.MySpringApplicationRunListener.<init>(org.springframework.boot.SpringApplication, [Ljava.lang.String;)
public MySpringApplicationRunListener(SpringApplication application, String[] args) {
}
@Override
public void starting() {
System.out.println("starting....项目启动中");
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
System.out.println("environmentPrepared...环境对象开始准备");
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
System.out.println("contextPrepared...上下文开始准备");
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
System.out.println("contextLoaded...上下文开始加载");
}
@Override
public void started(ConfigurableApplicationContext context) {
System.out.println("started...上下文对象加载完成");
}
@Override
public void running(ConfigurableApplicationContext context) {
System.out.println("running...项目启动完成,开始运行");
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
System.out.println("failed...项目运行失败");
}
}
- 如果没有创建对应的启动初始化配置,SpringApplicationRunListener实现类不会加载
- 所以需要创建 spring-factories
9.2.2 META_INF/spring-factories
org.springframework.boot.SpringApplicationRunListener=com.example.demo.listener.MySpringApplicationRunListener
运行后即可看到对应的MySpringApplicationRunListener 实现类被加载
9.3 CommandLineRunner 示例
9.3.1 CommandLineRunner 实现类 MyCommandLineRunner
// 项目启动时就会运行
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("MyCommandLineRunner....run");
System.out.println(Arrays.asList(args));
}
}
9.4 ApplicationRunner 示例
9.4.1 ApplicationRunner 实现类
// 项目启动时就会运行
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("MyApplicationRunner...run");
System.out.println(Arrays.asList(args.getSourceArgs()));
}
}
执行顺序
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.7.RELEASE)
ApplicationContextInitializer....initialize
contextPrepared...上下文开始准备
2022-08-12 10:41:38.763 INFO 25881 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication on JohnsondeMacBook-Pro.local with PID 25881 (/Users/johnsonzhou/Desktop/所有内容/学习/Java学习资料/practice_project/springboot-listener/target/classes started by johnsonzhou in /Users/johnsonzhou/Desktop/所有内容/学习/Java学习资料/practice_project/springboot-listener)
2022-08-12 10:41:38.765 INFO 25881 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
contextLoaded...上下文开始加载
2022-08-12 10:41:39.268 INFO 25881 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.83 seconds (JVM running for 1.487)
started...上下文对象加载完成
MyApplicationRunner...run
[name=johnson]
MyCommandLineRunner....run
[name=johnson]
running...项目启动完成,开始运行
10 流程分析
11 SpringBoot监控 actuator
11.1 引入pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
11.2 application.properties
# 应用名称
spring.application.name=demo
# Actuator Web 访问端口
management.server.port=8081
management.endpoints.jmx.exposure.include=*
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
# 应用服务 WEB 访问端口
server.port=8080
# redis地址
spring.redis.host=192.168.1.128
spring.redis.port=6379
11.3 访问 http://localhost:8080/actuator,就可以看到对应的返回结果
12 SpringBoot admin图形化界面
12.1 创建actuator server
springboot-admin-server
12.1.1 引入pom依赖
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
12.1.2 application.properties
# 应用名称
spring.application.name=demo
server.port=9000
12.1.3 服务启动类 使用 @EnableAdminServer 开启server
//开启admin服务
@EnableAdminServer
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
12.2 创建actuator server
springboot-admin-client
12.2.1 引入pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
12.2.2 application.properties
# 应用名称
spring.application.name=demo
# Actuator Web 访问端口
#management.endpoints.jmx.exposure.include=*
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
#执行admin.server地址
spring.boot.admin.client.url=http://localhost:9000/
12.2.3 开启服务后,在浏览器 访问 http://localhost:9000/ 则可看到对应的图形界面
13 SpringBoot部署
13.1 jar方式
运行jar包的两种方式
1. java -jar Test.jar
//指定入口类
2. java -cp com.test.Test Test.jar
13.2 war方式
13.2.1 更改打包方式,pom依赖中更改
<!-- 更改打包方式-->
<packaging>war</packaging>
13.2.2 启动类中继承SpringBootServletInitializer 并重写configure 方法
@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(DemoApplication.class);
}
}