Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

部分 IV. Spring Boot

目录

26. Spring Boot Quick start
26.1. 创建项目
26.2. pom.xml
26.3. Controller
26.4. Springboot with Maven
26.4.1. resource
26.4.2. Maven run
26.4.3. Spring Boot maven 插件 build-image
26.4.4. 生成项目信息
27. Spring 开发环境
27.1. Java 开发环境
27.2. 安装 Spring Tool Suite
27.3. Dashboard
27.4. Spring Initializr - Bootstrap your application
28. SpringApplication
28.1. 运行 Spring boot 项目
28.1.1. Linux systemd
28.1.2. 传统 init.d 脚本
28.1.3. 编译用于Tomcat的 War
28.2. @SpringBootApplication
28.2.1. 排除 @EnableAutoConfiguration 加载项
28.3. 获取 Resources 目录中的静态文件
28.4. @EnableAutoConfiguration
28.5. @ComponentScan
28.6. @EntityScan 实体扫描
28.7. @EnableJpaRepositories
28.8. 启动和销毁
28.9. 打印环境变量
28.10. CharacterEncodingFilter
28.11. 隐藏 Banner
28.12. 实体与仓库扫描
28.13. 列出 Beans
28.14. Tomcat 端口
28.15. 配置项设定
28.16. spring.profiles.active
28.17. @Profile("dev") / @ActiveProfiles("dev")
28.18. 设置默认时区
29. 如何优雅停止 Springboot 运行
29.1. 准备工作
29.2. kill 命令演示
29.3. 容器中如何优雅关闭 Springboot
29.4. 写入PID文件
30. Properties 配置文件
30.1. application.properties 配置文件
30.1.1. application.properties 参考
30.1.2. 启动指定参数
30.1.3. 加载排除
30.1.4. PID FILE
30.1.5. banner 关闭
30.1.6. server
30.1.7. logging
30.1.8. 内嵌 tomcat server
30.1.9. servlet
30.1.10. JSON 输出与日期格式化
30.1.11. SMTP 相关配置
30.1.12. Redis
30.1.13. MongoDB
30.1.14. MySQL
30.1.15. Oracle
30.1.16. default_schema
30.1.17. datasource
30.1.18. velocity
30.1.19. Security 相关配置
30.1.20. MVC 配置
30.1.21. Kafka 相关配置
30.2. Properties 文件
30.2.1. @Value 注解
30.2.2. @EnableConfigurationProperties 引用自定义 *.properties 配置文件
30.2.3. @PropertySource 注解载入 properties 文件
30.3. Environment 读取配置文件
30.4. 手工载入 *.properties 文件
30.5. 命令行注入配置项
30.5.1. spring.profiles.active 参数切换配置文件
30.5.2. SpringApplicationBuilder.properties() 方法添加配置项
30.5.3. 禁用命令行注入环境变量
30.6.
30.7. PropertyResolver 获取配置
30.8. 参数引用
30.9. 默认值
30.10. 产生随机数
30.10.1. 随机数
30.11. 多行字符串
30.12. 注入多值属性 arrays, list, set
30.13. List 列表类型
30.14. Map类型
30.15. Binder
30.16. 加密 application.properties 中的敏感内容
31. Spring boot with Logging
31.1. 配置日志文件
31.1.1. 日志输出级别
31.1.2. Spring boot 2.1 以后的版本不打印 Mapped 日志问题
31.1.3. 禁止控制台输出日志
31.1.4. 定制日志格式
31.1.5. 彩色输出
31.2. 打印日志
31.2.1. lombok
31.3. logback 配置详解
31.3.1. 标准输出
31.3.2. 禁止 logback 日志输出
31.3.3. 指定Class过滤日志
31.3.4. configuration 属性配置
31.3.5. contextName 设置上下文名称
31.3.6. property 设置变量
31.3.7. encoder 日志格式设置
31.3.8. RollingFileAppender
31.3.9. 日志过滤
31.3.10. 标准输出
31.3.11. MDC
31.3.12. 日志写入 MongoDB
31.3.13. 日志发送给 logstash
31.3.14. fluentd
31.3.15. Loki4j Logback
31.4. Log4j2 + Gelf + Logstash
31.4.1. Maven 配置
31.4.2. log4j2.xml 配置
31.4.3. Java 测试代码
31.4.4. Logstash 配置
31.4.5. 测试结果
31.4.6. Log4j2 更多技巧
31.5. 日志报警
31.5.1. Logstash 配置
31.5.2. 监控 SpringBootApplication 的启动和退出
31.6. Spring boot with ELK(Elasticsearch + Logstash + Kibana)
31.6.1. TCP 方案
31.6.2. Redis 方案
31.6.3. Kafka 方案
31.6.4. Other
32. Spring boot with Undertow
32.1. Maven 依赖
32.2. Application
32.3. 相关配置
33. Spring boot with Jetty
34. Spring boot with HTTP2 SSL
34.1. 生成自签名证书
34.2. application.properties 配置文件
34.3. 启动 Spring boot
34.4. restTemplate 调用实例
34.5. HTTP2
35. Spring boot with MongoDB
35.1. Maven
35.2. Application
35.3. MongoTemplate
35.4. Repository
36. Spring boot with MySQL
36.1. Maven
36.2. Resource
36.3. Application
36.4. JdbcTemplate
36.5. CrudRepository
37. Spring boot with Oracle
37.1. Maven
37.2. application.properties
37.3. Application
37.4. CrudRepository
37.5. JdbcTemplate
37.6. Controller
38. Spring boot with PostgreSQL
38.1. pom.xml
38.2. application.properties
38.3. Application
38.4. CrudRepository
38.5. JdbcTemplate
38.6. Controller
38.7. Test
39. Spring boot with Elasticsearch
39.1. Maven
39.2. Application
39.3. application.properties
39.4. Domain
39.5. ElasticsearchRepository
40. Spring boot with Elasticsearch TransportClient
40.1. Maven
40.2. Application
40.3. application.properties
40.4. ElasticsearchConfiguration
40.5. RestController
41. Spring boot with Apache Hive
41.1. Maven
41.2. application.properties
41.3. Configuration
41.4. CURD 操作实例
42. Spring boot with Phoenix
42.1. Maven
42.2. application.properties
42.3. Configuration
43. Spring boot with Datasource
43.1. Master / Slave 主从数据库数据源配置
43.1.1. application.properties
43.1.2. 配置主从数据源
43.1.3. 选择数据源
43.2. 多数据源配置
43.3. JPA 多数据源
44. 连接池配置
44.1. org.apache.tomcat.jdbc.pool.DataSource
44.2. druid
44.2.1. 加密数据库密码
44.3. c3p0 - JDBC3 Connection and Statement Pooling
44.4. dbcp2
44.5. bonecp
44.6. HikariPool
45. Spring boot with Queue
45.1. Spring boot with RabbitMQ(AMQP)
45.1.1. maven
45.1.2. RabbitMQConfig
45.1.3. 生产者
45.1.4. 消费者
45.2. Spring boot with Apache Kafka
45.2.1. 安装 kafka
45.2.2. maven
45.2.3. Spring boot Application
45.2.4. EnableKafka
45.2.5. KafkaListener
45.2.6. 测试
45.2.7. 完整的发布订阅实例
45.2.8. Spring cloud with Kafka
46. Spring boot with Scheduling
46.1. 启用计划任务
46.1.1. Application.java
46.1.2. 配置
46.1.3. Component
46.2. 计划任务控制开关
46.3. @Scheduled 详解
46.3.1. fixedRate 案例
46.3.2. timeUnit
46.4. cron 表达式
46.4.1. 每3秒钟一运行一次
46.4.2. 凌晨23点运行
46.4.3. 周一 ~ 周五
46.5. Timer 例子
46.6. ScheduledExecutorService 例子
47. Spring boot with Swagger
47.1. Spring boot with Springdoc
47.1.1. WebMvc
47.1.2. Webflux
47.1.3. Swagger UI
47.1.4. 从 SpringFox 迁移到 Swagger3 注解变化
47.2. Spring boot with knife4j
47.2.1. maven
47.2.2. Knife4jConfiguration
47.2.3. application.properties
47.3. springfox
47.3.1. Swagger3
47.3.2. Swagger2
47.3.3. @Api() 资源定义
47.3.4. @ApiIgnore 忽律接口
47.3.5. @ApiOperation()
47.3.6. @ApiResponses
47.3.7. @ApiModel 实体类
48. Spring boot with lombok
48.1. @Builder
48.2. @Slf4j 注解
49. Spring boot with Container
49.1. Spring boot with Docker
49.1.1. 通过 Docker 命令构建镜像
49.1.2. 通过 Maven 构建 Docker 镜像
49.1.3. [ERROR] No plugin found for prefix 'dockerfile' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (/Users/neo/.m2/repository), central (https://repo.maven.apache.org/maven2)] -> [Help 1]
49.1.4. curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:8888
49.2. Spring boot with Docker stack
49.2.1. 编译 Docker 镜像
49.2.2.
49.3. Spring boot with Kubernetes
49.3.1. Kubernetes 编排脚本
49.3.2. 部署镜像
50. Spring boot with command line
50.1. Maven
50.2. CommandLineRunner 例子
50.3. ApplicationRunner 例子
51. Spring Boot Actuator
51.1. Maven 依赖
51.2. 与 Spring Boot Actuator 有关的配置
51.2.1. 禁用HTTP端点
51.2.2. 安全配置
51.2.3. 修改 actuator 地址
51.2.4. 关机
51.3. actuator 接口
51.4. 健康状态
51.4.1. 健康状态
51.5. info 配置信息
51.6. beans 信息
51.7. caches
51.8. conditions
51.9. configprops 配置文件
51.10. env 环境变量
51.11. logfile 日志
51.12. threaddump 线程信息
51.13. 计划任务
51.14. metrics
51.15. 控制器映射 URL
51.16. 自定义监控指标
52. SpringBootTest
52.1. Maven 依赖
52.2. 测试类
52.2.1. Junit基本注解介绍
52.3.
52.3.1. Assert.assertEquals 判断相等
52.3.2. Assert.assertTrue
52.4. JPA 测试
52.5. TestRestTemplate
52.6. Controller单元测试
52.7. WebTestClient
53. Spring boot with Aop
53.1. Aspect
53.1.1. Maven
53.1.2. Pojo 类
53.1.3. Service 类
53.1.4. Aspect 类
53.1.5. 控制器
53.1.6. Application
53.1.7. 测试
54. Spring boot with starter
54.1. 实现 starter
54.1.1. Maven pom.xml 依赖包
54.1.2. 配置文件处理
54.1.3. 自动配置文件
54.1.4. 启用 starter 的自定义注解
54.2. 引用 starter
54.2.1. Maven pom.xml 引入依赖
54.2.2. 通过注解配置 starter
54.2.3. 测试运行结果
55. Spring boot with Monitor
55.1. Spring boot with Grafana
55.1.1. Springboot 集成 InfluxDB
55.1.2. InfluxDB
55.2. Spring Boot with Prometheus
55.2.1. Maven 依赖
55.2.2. application.properties 配置文件
55.2.3. 启动类
55.2.4. 测试
55.2.5. 控制器监控
55.2.6. 自定义埋点监控
57. Spring boot with Git version
57.1. CommonRestController 公共控制器
57.2. VersionRestController 测试控制器
57.3. 创建 .gitattributes 文件
58. Spring boot with Session share
58.1. Redis
58.1.1. Maven
58.1.2. application.properties
58.1.3. Application
58.2. 测试 Session
58.3. JDBC
58.4. Springboot 2.1
59. Spring boot with Caching
59.1. maven
59.1.1. Redis
59.2. 启用 Cache
59.3. @Cacheable 的用法
59.3.1. SpEL表达式
59.3.2. 排除 null 结果
59.3.3. 排除 empty
59.4. @CachePut 用法
59.5. 清空缓存
59.6. @Caching
59.7. 解决Expire 和 TTL 过期时间
60. Spring boot with Email
60.1. Maven
60.2. Resource
60.3. POJO
60.4. RestController
60.5. Test
61. Spring boot with Hessian
61.1. Maven
61.2. Application
61.3. HessianServiceExporter
61.4. Service
61.5. RestController
62. Spring boot with Async
62.1. Callable 实现异步
62.2. WebAsyncTask 实现异步
62.3. DeferredResult 实现异步返回结果
62.4. 带有返回值的异步任务
62.4.1. Future
62.4.2. CompletableFuture
62.5. 默认简单线程池 SimpleAsyncTaskExecutor
62.5.1. 配置线程池
62.5.2. @Service/@Component 中异步执行
62.5.3. applicationTaskExecutor
62.6. ThreadPoolTaskExecutor 自定义线程池
62.6.1. 最简单的配置
62.6.2. 队列
62.6.3. 定义多个线程池
62.6.4. 实现 AsyncConfigurer 接口方式创建自定义连接池
62.6.5. 继承 AsyncConfigurerSupport 创建自定义连接池
62.6.6. 生产环境完整代码 @Bean 注入方式
62.6.7. 通过 @Bean 覆盖掉 SimpleAsyncTaskExecutor
62.7. 自定义线程池 ThreadPoolExecutor
62.7.1. ThreadPoolExecutor
62.7.2. 注入自定义线程池bean
62.8. 设置线程名称
62.9. 线程池监控
62.10. 注意事项
63. Springboot with Ethereum (web3j)
63.1. Maven
63.2. application.properties
63.3. TestRestController
63.4. 测试
64. Java Record 新特性
64.1. Record 替代 POJO 类
64.2. Record 作为 Properties
64.3. Record 作为实体类
64.4. Record 作为 Service
64.5. Record 作为 Controller

1. Spring boot with Redis

1.1. Spring boot with Redis

1.1.1. maven

				
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>			
				
			

1.1.2. application.properties

				
spring.redis.database=10
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.timeout=0
				
			

1.1.3. JUnit

				
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class ApplicationTests {
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	@Test
	public void test() throws Exception {
		// 保存字符串
		stringRedisTemplate.opsForValue().set("neo", "chen");
		Assert.assertEquals("chen", stringRedisTemplate.opsForValue().get("neo"));
    }
}				
				
			

1.1.4. Controller

stringRedisTemplate模板用于存储key,value为字符串的数据

				
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	@RequestMapping("/test")
	@ResponseBody
	public String test() {
		String message = "";
		stringRedisTemplate.opsForValue().set("hello", "world");
		message = stringRedisTemplate.opsForValue().get("hello");
		return message;
	}
				
			

等同于

				
	@Autowired
	private RedisTemplate<String, String> redisTemplate;
				
			

例 8. RedisTemplate

					
	@Autowired
	private RedisTemplate<String, String> redisTemplate;
	
	public List<Protocol> getProtocol() {
		List<Protocol> protocols = new ArrayList<Protocol>();
		Gson gson = new Gson();
		Type type = new TypeToken<List<Protocol>>(){}.getType();
		redisTemplate.setKeySerializer(new StringRedisSerializer());
		redisTemplate.setValueSerializer(new StringRedisSerializer());
		
		String cacheKey = String.format("%s:%s", this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName());
		long expireTime = 5;
		
		if(redisTemplate.hasKey(cacheKey)){
			String cacheValue = redisTemplate.opsForValue().get(cacheKey);
			System.out.println(cacheValue);
			protocols = gson.fromJson(cacheValue, type);
		}else{
			Protocol protocol = new Protocol();
			protocol.setRequest(new Date().toString());
			protocols.add(protocol);
			
			String jsonString = gson.toJson(protocols, type);
	        System.out.println( jsonString );
			
			redisTemplate.opsForValue().set(cacheKey, jsonString);
			redisTemplate.expire(cacheKey, expireTime, TimeUnit.SECONDS);
		}
		return protocols;
	}
					
				

1.2. Redis Pub/Sub

1.2.1. Redis配置类

				
package cn.netkiller.wallet.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

import cn.netkiller.wallet.redis.RedisMessageSubscriber;

@Configuration
public class RedisConfig {

	public RedisConfig() {
	}

	@Bean
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
		StringRedisTemplate redisTemplate = new StringRedisTemplate();
		redisTemplate.setConnectionFactory(connectionFactory);
		return redisTemplate;
	}

	@Bean
	public MessageListenerAdapter messageListener() {
		return new MessageListenerAdapter(new RedisMessageSubscriber());
	}

	@Bean
	public ChannelTopic topic() {
		return new ChannelTopic("demo");
	}

	@Bean
	public RedisMessageListenerContainer redisContainer(RedisConnectionFactory connectionFactory, MessageListenerAdapter messageListener) {
		RedisMessageListenerContainer container = new RedisMessageListenerContainer();

		container.setConnectionFactory(connectionFactory);
		container.addMessageListener(messageListener(), topic());
		container.addMessageListener(messageListener(), new ChannelTopic("test"));
		return container;
	}

}

				
			

1.2.2. 订阅和发布类

				
package cn.netkiller.wallet.redis;

import java.nio.charset.StandardCharsets;

import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;

public class RedisMessageSubscriber implements MessageListener {
	public void onMessage(final Message message, final byte[] pattern) {
		System.out.println("Topic : " + new String(message.getChannel(), StandardCharsets.UTF_8));
		System.out.println("Message : " + message.toString());
	}
}

				
			
				
package cn.netkiller.wallet.redis;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;

public class RedisMessagePublisher {

	private final StringRedisTemplate redisTemplate;

	private final ChannelTopic topic;

	public RedisMessagePublisher(StringRedisTemplate redisTemplate, ChannelTopic topic) {
		this.redisTemplate = redisTemplate;
		this.topic = topic;
	}

	public void publish(String message) {
		redisTemplate.convertAndSend(topic.getTopic(), message);
	}
}
								
				
			

1.2.3. 消息发布演示

				
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	@GetMapping("/pub/demo")
	public String pub() {

		RedisMessagePublisher publisher = new RedisMessagePublisher(stringRedisTemplate, new ChannelTopic("demo"));
		String message = "Message " + UUID.randomUUID();
		publisher.publish(message);
		return message;
	}

	@GetMapping("/pub/test")
	public String pub(@RequestParam String message) {

		RedisMessagePublisher publisher = new RedisMessagePublisher(stringRedisTemplate, new ChannelTopic("test"));
		publisher.publish(message);
		return message;
	}				
				
			

1.3. Sprint boot with Redisson

1.3.1. Springboot 3.x

		

		
			

1.3.2. Springboot 2.1

注意:排除 redisson-spring-data-23,引用 redisson-spring-data-21

		
 		<dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.14.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.redisson</groupId>
                    <artifactId>redisson-spring-data-23</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-data-21</artifactId>
            <version>3.14.0</version>
        </dependency>