SpringBoot高级
1.自动配置-Condition
Condition是Spring4.0后引入的条件化配置接口,通过实现Condition接口可以完成有条件的加载相应的Bean
进入 SpringBoot 启动类,点击进入 run()
可以看到这个方法是有返回值的,返回值为 ConfigurableApplicationContext
这个返回值就是 IOC 容器
通过获取 run() 的返回值再获取容器中的bean
导入redis起步依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
@SpringBootApplication
public class SpringbootConditionApplication {public static void main(String[] args) {//启动SpringBoot的应用,返回Spring的IOC容器ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);//获取Bean,RedisTemplateObject redisTemplate = context.getBean("redisTemplate");System.out.println(redisTemplate);}
案例
在Spring的IOC容器中有一个User的Bean,现要求:
1.导入Jedis坐标后,加载该Bean,没导入,则不加载
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency>
package com.domain;public class User {
}
package com.config;import com.condition.ClassCondition;
import com.domain.User;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;@Configuration
public class UserConfig {@Bean@Conditional(ClassCondition.class)public User user(){return new User();}
}
package com.condition;import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;public class ClassCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {//需求:导入Jedis坐标后创建Bean//思路:判断redis.clients.jedis.Jedis.class文件是否存在boolean flag = true;try {Class<?> cls = Class.forName("redis.clients.jedis.Jedis");} catch (ClassNotFoundException e) {flag = false;}return flag;}
}
package com.springbootcondition;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication
public class SpringbootConditionApplication {public static void main(String[] args) {//启动SpringBoot的应用,返回Spring的IOC容器ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);//获取Bean,RedisTemplate/*Object redisTemplate = context.getBean("redisTemplate");System.out.println(redisTemplate);*/Object user = context.getBean("user");System.out.println(user);}}
如果把 pom.xml 文件中的 Jedis 坐标注释掉
那么Spring 容器则不会创建 User 对应的 Bean,运行启动类就获取不到 user 对象
2.将类的判断定义为动态的。判断哪个字节码文件存在可以动态指定
package com.condition;import org.springframework.context.annotation.Conditional;import java.lang.annotation.*;@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ClassCondition.class)
public @interface ConditionOnClass {String[] value();
}
package com.condition;import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;import java.util.Map;
import java.util.Objects;public class ClassCondition implements Condition {//context 上下文对象。用于获取环境,IOC容器,ClassLoader对象//metadata 注解元对象。可以用于获取注解定义的属性值/*@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {//需求1:导入Jedis坐标后创建Bean//思路:判断redis.clients.jedis.Jedis.class文件是否存在boolean flag = true;try {Class<?> cls = Class.forName("redis.clients.jedis.Jedis");} catch (ClassNotFoundException e) {flag = false;}return flag;}*/@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {//需求2:导入注解属性值value指定坐标后创建Bean//获取注解属性值 valueMap<String, Object> map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());//System.out.println(map);String[] value = (String[]) map.get("value");boolean flag = true;try {for (String className : value) {Class<?> cls = Class.forName("className");}} catch (ClassNotFoundException e) {flag = false;}return flag;}
}
package com.config;import com.condition.ConditionOnClass;
import com.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class UserConfig {@Bean//@Conditional(ClassCondition.class)@ConditionOnClass("redis.clients.jedis.Jedis")public User user(){return new User();}
}
package com.springbootcondition;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication
public class SpringbootConditionApplication {public static void main(String[] args) {//启动SpringBoot的应用,返回Spring的IOC容器ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);//获取Bean,RedisTemplate/*Object redisTemplate = context.getBean("redisTemplate");System.out.println(redisTemplate);*/Object user = context.getBean("user");System.out.println(user);}}
Condition-小结
自定义条件
1.定义条件类:自定义类实现 Condition 接口,重写 matches 方法,在 matches 方法中进行逻辑判断,返回 boolean 值。matches 方法两个参数:
context:上下文对象,可以获取属性值、类加载器、BeanFactory 等
metadata:元数据对象,用于获取注解属性
2.判断条件:在初始化 Bean 时,使用 @Conditional(条件类.class) 注解
SpringBoot 提供的常用条件注解:
ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean
ConditionalOnClass:判断内存在中是否有对应字节码文件才初始化Bean (jar 包有没有导入)
ConditionalOnMissingBean:判断容器中没有对应Bean才初始化Bean(执行这个方法时要求所依赖的bean 已经被初始化了)
2.切换内置web服务器
SpringBoot的web环境中默认使用tomcat作为内置服务器,其实SpringBoot提供了4种内置服务器供我们选择,我们可以很方便的进行切换
<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>
3.Enable注解原理
pringBoot中提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的。而其底层原理是使用@Import注解导入一些配置类,实现Bean的动态加载
package com.springbootenable;import com.config.EnableUser;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;/*** @ComponentScan 扫描范围:当前引导类所在包及其子包** com.springbootenable* com.config* //1.使用@ComponentScan扫描com.config包* //2.可以使用@Import注解,加载类。这些类都会被Spring创建,并放入IOC容器* //3.可以对Import注解进行封装。*///@ComponentScan("com.config")
//@Import(UserConfig.class)
@EnableUser
@SpringBootApplication
public class SpringbootEnableApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);//获取BeanObject user = context.getBean("user");System.out.println(user);}
}
pom中引入springboot-enable-other
记得在enable-other中打包(install)
<pendency><groupId>com</groupId><artifactId>springboot-enable-other</artifactId><version>0.0.1-SNAPSHOT</version></dependency>
package com.domain;public class User {
}
package com.config;import com.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class UserConfig {@Beanpublic User user(){return new User();}
}
package com.config;import org.springframework.context.annotation.Import;import java.lang.annotation.*;@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(UserConfig.class)
public @interface EnableUser {
}
SpringBoot不能直接获取在其他工程中定义的Bean
原因:@ComponentScan 扫描范围:当前引导类所在包及其子包
三种解决方案:
1.使用@ComponentScan扫描com.lichee.config包
2.可以使用@Import注解,加载类。这些类都会被Spring创建,并放入IOC容器
3.可以对Import注解进行封装
注:Enable注解底层原理是使用@Import注解实现Bean的动态加载
4.@Import详解
@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@Import提供4中用法:
1.导入Bean
2.导入配置类
3.导入 ImportSelector 实现类。一般用于加载配置文件中的类
4.导入 ImportBeanDefinitionRegistrar 实现类。
package com.domain;public class Role {
}
package com.config;import com.domain.Role;
import com.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class UserConfig {@Beanpublic User user(){return new User();}@Beanpublic Role role(){return new Role();}
}
导入Bean @Import(User.class)
导入配置类 @Import(UserConfig.class)
导入 ImportSelector 实现类 @Import(MyImportSelector.class)
package com.springbootenable;import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.domain.User", "com.domain.Role"};}
}
导入 ImportBeanDefinitionRegistrar 实现类。@Import({MyImportBeanDefinitionRegistrar.class})
package com.springbootenable;import com.domain.User;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();registry.registerBeanDefinition("user", beanDefinition);}
}
SpringbootEnableApplication测试代码
package com.springbootenable;import com.config.EnableUser;
import com.domain.Role;
import com.domain.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;import java.util.Map;/**- Import4中用法:- 1. 导入Bean- 2. 导入配置类- 3. 导入ImportSelector的实现类。- 4. 导入ImportBeanDefinitionRegistrar实现类*///@Import(User.class)
//@Import(UserConfig.class)
//@Import(MyImportSelector.class)
@Import({MyImportBeanDefinitionRegistrar.class})@SpringBootApplication
public class SpringbootEnableApplication {public static void main(String[] args) {ConfigurableApplicationContext context =SpringApplication.run(SpringbootEnableApplication.class, args);/*//获取BeanObject user = context.getBean("user");System.out.println(user);*//*User user = context.getBean(User.class);System.out.println(user);Role role = context.getBean(Role.class);System.out.println(role);*/Object user = context.getBean("user");System.out.println(user);/*Map<String, User> map = context.getBeansOfType(User.class);System.out.println(map);*/}
}
5.@EnableAutoConfiguration详解
@EnableAutoConfiguration 注解内部使用@Import(AutoConfigurationImportSelector.class)来加载配置类
配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当 SpringBoot 应用启动时,会自动加载这些配置类,初始化Bean
并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean
6.自定义starter配置
需求:自定义redis-starter。要求当导入redis坐标时,SpringBoot自动创建Jedis的Bean
步骤分析
1.创建 redis-spring-boot-autoconfigure 模块
2.创建 redis-spring-boot-starter 模块,依赖 redis-spring-boot-autoconfigure的模块
3.在 redis-spring-boot-autoconfigure 模块中初始化 Jedis 的 Bean。并定义META-INF/spring.factories 文件
4.在测试模块中引入自定义的 redis-starter 依赖,测试获取 Jedis 的Bean,操作 redis
实现
创建redis-spring-boot-starter工程
pom文件中引入redis-spring-boot-autoconfigure
<!--引入configure--><dependency><groupId>com</groupId><artifactId>redis-springboot-autoconfigure</artifactId><version>0.0.1-SNAPSHOT</version></dependency>
创建redis-spring-boot-autoconfigure配置工程
@ConfigurationProperties(prefix = "redis")
public class RedisProperties {private String host = "localhost";private int port = 6379;public String getHost() {return host;}public void setHost(String host) {this.host = host;}public int getPort() {return port;}public void setPort(int port) {this.port = port;}
}
package com.springbootautoconfigure;import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {/*** 提供Jedis的bean*/@Beanpublic RedisProperties.Jedis jedis(RedisProperties redisProperties) {return new RedisProperties.Jedis(redisProperties.getHost(), redisProperties.getPort());}
}
在resource目录下创建META-INF文件夹并创建spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.lichee.redis.config.RedisAutoConfiguration
注意:”\ “是换行使用的
在springboot-enable工程中引入自定义的redis的starter
<!--自定义的redis的starter-->
<dependency><groupId>com</groupId><artifactId>redis-springboot-starter</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>
在SpringbootEnableApplication启动类中测试
Jedis jedis = context.getBean(Jedis.class);System.out.println(jedis);
测试springboot-enable工程中的application.properties中的配置参数
redis.port=6666
使用注解完成有条件加载配置类
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
@ConditionalOnClass(Jedis.class)
public class RedisAutoConfiguration {/*** 提供Jedis的bean*/@Bean@ConditionalOnMissingBean(name = "jedis")public Jedis jedis(RedisProperties redisProperties) {System.out.println("RedisAutoConfiguration....");return new Jedis(redisProperties.getHost(), redisProperties.getPort());}
}
7.SpringBoot事件监听
Java中的事件监听机制
事件:Event,继承 java.util.EventObject 类的对象
事件源:Source ,任意对象Object
监听器:Listener,实现 java.util.EventListener 接口 的对象
SpringBoot 在项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在项目启动时完成一些操作
ApplicationContextInitializer、
SpringApplicationRunListener、
CommandLineRunner、
ApplicationRunner
package com.springbootlistener.listener;import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;@Component
public class MyApplicationContextInitializer implements ApplicationContextInitializer {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {System.out.println("ApplicationContextInitializer....initialize");}
}
package com.springbootlistener.listener;import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;import java.util.Arrays;/*** 当项目启动后执行run方法。*/
@Component
public class MyApplicationRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {System.out.println("ApplicationRunner...run");System.out.println(Arrays.asList(args.getSourceArgs()));}
}
package com.springbootlistener.listener;import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;import java.util.Arrays;@Component
public class MyCommandLineRunner implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {System.out.println("CommandLineRunner...run");System.out.println(Arrays.asList(args));}
}
MyApplicationContextInitializer的使用要在resource文件夹下添加META-INF/spring.factories
org.springframework.context.ApplicationContextInitializer=com.springbootlistener.listener.MyApplicationContextInitializer
org.springframework.boot.SpringApplicationRunListener=com.springbootlistener.listener.MySpringApplicationRunListener
MySpringApplicationRunListener的使用要添加构造器
package com.springbootlistener.listener;import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;public class MySpringApplicationRunListener implements SpringApplicationRunListener {public MySpringApplicationRunListener(SpringApplication application, String[] args) {}@Overridepublic void starting() {System.out.println("starting...项目启动中");}@Overridepublic void environmentPrepared(ConfigurableEnvironment environment) {System.out.println("environmentPrepared...环境对象开始准备");}@Overridepublic void contextPrepared(ConfigurableApplicationContext context) {System.out.println("contextPrepared...上下文对象开始准备");}@Overridepublic void contextLoaded(ConfigurableApplicationContext context) {System.out.println("contextLoaded...上下文对象开始加载");}@Overridepublic void started(ConfigurableApplicationContext context) {System.out.println("started...上下文对象加载完成");}@Overridepublic void running(ConfigurableApplicationContext context) {System.out.println("running...项目启动完成,开始运行");}@Overridepublic void failed(ConfigurableApplicationContext context, Throwable exception) {System.out.println("failed...项目启动失败");}
}
8.SpringBoot流程分析-初始化
配置启动引导类(判断是否有启动主类)
判断是否是Web环境
获取初始化类、监听器类
9.SpringBoot流程分析-run
1.启动计时器
2.执行监听器
3.准备环境
4.打印banner:可以resource下粘贴自定义的banner
5.创建context
refreshContext(context);
执行refreshContext方法后才真正创建Bean
10.SpringBoot监控-actuator基本使用
监控概述
SpringBoot自带监控功能Actuator,可以帮助实现对程序内部运行情况监控,比如监控状况,Bean加载情况,配置属性,日志信息等
监控使用
1.导入依赖坐标
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.访问http://localhost:8080/acruator
{"_links":{"self":{"href":"http://localhost:8080/actuator","templated":false},"health":{"href":"http://localhost:8080/actuator/health","templated":false},"health-component-instance":{"href":"http://localhost:8080/actuator/health/{component}/{instance}","templated":true},"health-component":{"href":"http://localhost:8080/actuator/health/{component}","templated":true},"info":{"href":"http://localhost:8080/actuator/info","templated":false}}
}
在application.properties中配置
info.name=zhangsan
info.age=23
http://localhost:8080/actuator/info
开启健康检查详细信息
management.endpoint.health.show-details=always
{"status":"UP","components":{"diskSpace":{"status":"UP","details":{"total":256048623616,"free":41103265792,"threshold":10485760,"exists":true}},"ping":{"status":"UP"}}
}
11.SpringBoot监控-actuator开启所有endpoint
开启所有endpoint
在application.properties中配置:
#将所有的监控endpoint暴露出来
management.endpoints.web.exposure.include=*
{"_links":{"self":{"href":"http://localhost:8080/actuator","templated":false},"beans":{"href":"http://localhost:8080/actuator/beans","templated":false},"caches-cache":{"href":"http://localhost:8080/actuator/caches/{cache}","templated":true},"caches":{"href":"http://localhost:8080/actuator/caches","templated":false},"health":{"href":"http://localhost:8080/actuator/health","templated":false},"health-path":{"href":"http://localhost:8080/actuator/health/{*path}","templated":true},"info":{"href":"http://localhost:8080/actuator/info","templated":false},"conditions":{"href":"http://localhost:8080/actuator/conditions","templated":false},"configprops":{"href":"http://localhost:8080/actuator/configprops","templated":false},"configprops-prefix":{"href":"http://localhost:8080/actuator/configprops/{prefix}","templated":true},"env":{"href":"http://localhost:8080/actuator/env","templated":false},"env-toMatch":{"href":"http://localhost:8080/actuator/env/{toMatch}","templated":true},"loggers":{"href":"http://localhost:8080/actuator/loggers","templated":false},"loggers-name":{"href":"http://localhost:8080/actuator/loggers/{name}","templated":true},"heapdump":{"href":"http://localhost:8080/actuator/heapdump","templated":false},"threaddump":{"href":"http://localhost:8080/actuator/threaddump","templated":false},"metrics-requiredMetricName":{"href":"http://localhost:8080/actuator/metrics/{requiredMetricName}","templated":true},"metrics":{"href":"http://localhost:8080/actuator/metrics","templated":false},"scheduledtasks":{"href":"http://localhost:8080/actuator/scheduledtasks","templated":false},"mappings":{"href":"http://localhost:8080/actuator/mappings","templated":false}}
}
12.SpringBoot监控-springboot admin图形化界面使用
SpringBoot 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:
1创建 admin-server 模块
2导入依赖坐标 admin-starter-server
<dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
3.在引导类上启用监控功能@EnableAdminServer
package com.springbootadminserver;import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@EnableAdminServer
@SpringBootApplication
public class SpringbootAdminServerApplication {public static void main(String[] args) {SpringApplication.run(SpringbootAdminServerApplication.class, args);}
}
admin-client:
1.创建 admin-client 模块
2.导入依赖坐标 admin-starter-client
<dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
3.配置相关信息:server地址等
server的application.properties
server.port=9000
client的
#执行admin.server地址
spring.boot.admin.client.url=http://localhost:9000management.endpoint.health.show-details=always
management.endpoints.web.exposure.include=*
4.启动server和client服务,访问server
http://localhost:9000/applications
idea中也有这样的功能
13.SpringBoot部署
SpringBoot 项目开发完毕后,支持两种方式部署到服务器:
1.jar包(官方推荐)
2.war包
不修改则默认为打jar包
更改pom文件中的打包方式为war
修改启动类
package com.springbootdeploy;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;@SpringBootApplication
public class SpringbootDeployApplication extends SpringBootServletInitializer {public static void main(String[] args) {SpringApplication.run(SpringbootDeployApplication.class, args);}@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {return builder.sources(SpringbootDeployApplication.class);}
}
packaging改为war
<name>springboot-deploy</name><description>springboot-deploy</description><packaging>war</packaging>
指定打包的名称
<build><finalName>springboot</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>
打出的war包名就为springboot
相关文章:

SpringBoot高级
1.自动配置-Condition Condition是Spring4.0后引入的条件化配置接口,通过实现Condition接口可以完成有条件的加载相应的Bean 进入 SpringBoot 启动类,点击进入 run() 可以看到这个方法是有返回值的,返回值为 ConfigurableApplicationConte…...

机试:偶数分解
题目描述: 代码示例: #include <bits/stdc.h> using namespace std; int main(){ // 算法思想1:遍历小于该偶数的所有素数,存入数组中,遍历数组找出两个数之和等于偶数的数int n;cout << "输入样例" << endl;cin >> n;int nums[n];int k …...

一周学会Django5 Python Web开发-Jinja3模版引擎-安装与配置
锋哥原创的Python Web开发 Django5视频教程: 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计35条视频,包括:2024版 Django5 Python we…...

python前端开发
前端开发 快速网站开发 from flask import Flask appFlask(__name__) #创建网址/show/info 和函数index的对应关系, #访问网站,执行index()函数 app.route("/show/info") def index():return "中国联通" if __name__"__main_…...

web学习笔记(三十三)
目录 1.严格模式 1.1严格模式的概念: 1.2严格模式在语义上更改的地方: 1.3如何开启严格模式 1.4严格模式应用上的变化 2.原型链 1.严格模式 1.1严格模式的概念: 严格模式有点像es5向es6过渡而产生的一种模式,因为es6的语法…...

flask库
文章目录 flask库1. 基本使用2. 路由路径和路由参数3. 请求跳转和请求参数4. 模板渲染1. 模板变量2. 过滤器3. 测试器 5. 钩子函数与响应对象 flask库 flask是python编写的轻量级框架,提供Werkzeug(WSGI工具集)和jinjia2(渲染模板…...

专业无网设备如何远程运维?向日葵远程控制能源场景案例解析
清洁能源领域,拥有庞大的上下游产业链,涉及的相关工业设备门类多、技术覆盖全、行业应用广。在这一领域内,相关专业设备的供应商的核心竞争力除了本身产品的技术能力之外,服务也是重要的一环。 某企业作为致力于节能环保方向的气…...

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的稻田虫害检测系统详解(深度学习+Python代码+UI界面+训练数据集)
摘要:本篇文章深入探讨了如何利用深度学习技术开发一个用于检测稻田虫害的系统,并且分享了完整的实现过程和资源代码下载。该系统采用了当前的YOLOv8、YOLOv7、YOLOv6、YOLOv5算法,对其进行了性能对比,包括mAP、F1 Score等关键指标…...

实现upt下客户端用tftp文件传输协议编写客户端发送下载文件
#include <myhead.h> #define SEP_IP #define SEP_PORT int main(int argc, const char *argv[]) {//创建套接字if(int crdsocket(AF_INET,SOCK-DGRAM)-1);{perror("socket error");return -1;}printf("创建成功\n");//填充地址struct sockaddr_in s…...

什么软件可以改ip地址
修改ip地址的软件有哪些,什么软件可以切换电脑手机的ip地址想必很多朋友都在寻找类似的软件,也想知道其中的答案,也能提高自己工作的效率。 经过小编在互联网摸爬滚打这些年,测试认证和整理后,发现一款名叫深度IP转换…...

C#,文字排版的折行问题(Word-wrap problem)的算法与源代码
1、英文的折行问题 给定一个单词序列,以及一行中可以输入的字符数限制(线宽)。 在给定的顺序中放置换行符,以便打印整齐。 假设每个单词的长度小于线宽。 像MS word这样的文字处理程序负责放置换行符。 这个想法是要有平衡的线条。…...

VUE+VScode+elementUI开发环境
0.vue官方文档 你正在阅读的是 Vue 3 的文档! 1.前端准备阶段 VUEVScodeelementUI开发环境 2.Vue外部组件 element-ui 3.angular外部组件 angular-ui 4.教学视频 尚学堂b站视频 5.教学视频配套文档 D:\BaiduNetdiskDownload\025【尚学堂】全新2022版WEB前端为初学者…...

第十四届蓝桥杯省赛真题 Java A 组【原卷】
文章目录 发现宝藏【考生须知】试题 A \mathrm{A} A : 特殊日期试题 B: 与或异或试题 C : \mathrm{C}: C: 平均试题 D: 棋盘试题 E : \mathrm{E}: E: 互质数的个数试题 F: 阶乘的和试题 G: 小蓝的旅行计划试题 H: 太阳试题 I: 高塔试题 J \mathrm{J} J : 反异或 01 串 发现…...

可视化展示与交互编辑:探索3D Web轻量化平台HOOPS WEB Platform在BIM中的新可能性
随着数字技术的飞速发展,建筑行业也在不断迈向数字化转型的道路。在这个过程中,BIM(Building Information Modeling,建筑信息模型)技术已经成为建筑设计、施工和管理领域中的一项重要工具。 而在BIM的应用中ÿ…...

Linux(centos)环境下安装Nginx的步骤文档
在Linux环境下安装Nginx是一个相对直接的过程,本篇文章将提供一个较为通用的安装指南,以及一些可能遇到的问题和解决方案。 目录 一、简介 二、先决条件 三、安装Nginx 1、使用包管理器安装 2、从源代码安装 四、验证安装 五、基本配置 六、常见…...

AI毕业论文降重GPTS,避免AI检测,高效完成论文
视频演示 AI毕业论文降重GPTS,避免AI检测,高效完成论文! 开发目的 “毕业论文降重”GPTS应用,作用为:重新表述学术论文,降低相似性评分,避免AI检测。 使用地址 地址:毕业论文降重…...

什么是线程死锁?形成死锁的四个必要条件是什么?如何避免线程死锁?
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 什么是线程死锁 线程死锁是指两个或多个线程由于互相持有对方所需要的资源而无法继续执行的情况。当多个线程同时占用资源,并等待其他线程释放它们所需要…...

webpack一些常用的Loader和Plugin
文章目录 webpack4一些常用的Loader:webpack4一些常用的Plugin:关于webpack5的一些特点:新增特性:修复的问题:内置模块和工具: 关于webpack5的一些内置:内置Loader:内置Plugin: webp…...

SpringCloud Bus 消息总线
一、前言 接下来是开展一系列的 SpringCloud 的学习之旅,从传统的模块之间调用,一步步的升级为 SpringCloud 模块之间的调用,此篇文章为第八篇,即介绍 Bus 消息总线。 二、概述 2.1 遗留的问题 在上一篇文章的最后,我…...

汽车屏类产品(五):仪表Cluster常用芯片i.MX117x
前言: 仪表一般就是指方向盘前面那个表盘。做仪表的芯片最主要需要支持显示Display,而仪表的主要排版布局多种多样,但是主旨显示内容不尽相同。 仪表需求: 1、rpm转速表盘 仪表Cluster一般会有转速表盘rpm,单位一般是x1000,大部分汽车仪表范围就是0~8,也就是最高8000…...

SQLiteC/C++接口详细介绍之sqlite3类(三)
快速跳转文章列表:SQLite—系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(二) 下一篇:SQLiteC/C接口详细介绍之sqlite3类(四) 6.sqlite3_create_module与sqlite3_create_module_v2函数…...

Xcode调试Qt 源码
在Mac下使用Xcode 开发Qt程序,由于程序断点或者崩溃后,Qt库的堆栈并不能够正确定位到源码的cpp文件,而是显示的是汇编代码,导致不直观的显示。 加载的其他三方库都是同理。 所以找了攻略和研究后,写的这篇文章。 一&a…...

CVE-2019-5782:kArgumentsLengthType 设置偏小导致优化阶段可以错误的去除 CheckBound 节点
文章目录 环境搭建漏洞分析笔者初分析笔者再分析漏洞触发源码分析 漏洞利用总结 环境搭建 sudo apt install pythongit reset --hard b474b3102bd4a95eafcdb68e0e44656046132bc9 export DEPOT_TOOLS_UPDATE0 gclient sync -D// debug version tools/dev/v8gen.py x64.debug ni…...

uni-app微信小程序上拉加载,下拉刷新
pages.json配置官网链接 onPullDownRefresh、onReachBottom函数跟生命周期同级 data() {return {orderList:[],total: null, //总共多少条数据page: 1,pageSize: 10,} }, onLoad() {}, mounted(){this.getInfo() }, methods:{getInfo(){API.getListxxx().then(res > {const…...
HTML案例-2.标签综合练习
目录 效果 知识点 1.图像标签 2.链接标签 3.锚点定位 4.base标签 源码 页面1 页面2 效果 知识点 1.图像标签 <img src="图像URL" /> 单标签 属性 属性值 描述 src URL 图像的路径 alt 文本...

C++中的多值返回:解锁函数返回值的神奇力量
C中的多值返回:解锁函数返回值的神奇力量 在C编程中,有时候我们需要从函数中返回多个值。虽然C中的函数通常只能返回一个值,但有几种技术和惯用法可以实现返回多个值的效果。本文将介绍C中实现多值返回的几种常用方法,包括引用、指…...

D咖智能咖啡机:营业利器,品质与效率的完美结合
D咖作为中国知名国产商用全自动咖啡机品牌,持续引领商用全自动智能咖啡机赛道技术、产品、创新的行业新标准,目前为全国几十个地区提供全场景自助咖啡机解决方案,并获得了广泛的认可和口碑。 一、便捷操作:一键即可享受美味咖啡 在…...

江科大stm32学习笔记【6-2】——定时器定时中断定时器外部时钟
一.定时器定时中断 1.原理 2.硬件 3.程序 此时CK_PSC72M,定时1s,也就是定时频率为1Hz,所以可以PSC7200-1,ARR10000-1。 Timer.c: #include "stm32f10x.h" // Device headerextern uint16_t Num;//声明跨文件的…...

go优雅重试
实现思路: 重试配置定义最大重试次数和固定重试间隔;使用接口优雅传递可选重试配置参数;重试的模板方法必须返回错误,且只有一个返回值;如果需要使用被重试方法的返回值,使用匿名方法包一层真实方法并在匿…...

Python最常用的库
本文章主要为大家总结,9个Python最常用的包及使用案例 1 NumPy 描述: NumPy 是 Python 的一个扩展库,支持高维数组与矩阵运算,并为数组运算提供了大量的数学函数库。它是科学计算中的基础包之一,用于处理大型多维数组和矩阵的运…...