技术交流总结:分布式、数据库、Spring及SpringBoot核心知识点梳理
一、分布式系统实战深度解析
1. Redis与数据库数据一致性保障架构
核心实现代码示例:
@Service
@Slf4j
public class OrderTimeoutService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private OrderRepository orderRepository;
@Autowired
private InventoryService inventoryService;
/**
* 订单创建时设置Redis超时Key
*/
public void createOrder(Order order) {
// 1. 数据库持久化
orderRepository.save(order);
// 2. Redis设置超时Key(30分钟)
String timeoutKey = "order:timeout:" + order.getId();
redisTemplate.opsForValue().set(timeoutKey, order.getId(), 30, TimeUnit.MINUTES);
// 3. 绑定Redis过期监听
redisTemplate.getConnectionFactory().getConnection()
.pSubscribe(new OrderTimeoutListener(), timeoutKey.getBytes());
}
/**
* Redis Key过期监听器
*/
private class OrderTimeoutListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] pattern) {
String orderId = new String(message.getBody());
cancelOrderIfNeeded(orderId);
}
}
/**
* 取消订单(核心一致性逻辑)
*/
@Transactional
public void cancelOrderIfNeeded(String orderId) {
// 1. 查询数据库订单状态
Order order = orderRepository.findById(orderId)
.orElseThrow(() -> new RuntimeException("订单不存在"));
// 2. 双重检查订单状态
if (OrderStatus.PENDING_PAYMENT.equals(order.getStatus())) {
// 3. 获取分布式锁,避免重复处理
String lockKey = "order:cancel:lock:" + orderId;
RLock lock = redissonClient.getLock(lockKey);
try {
if (lock.tryLock(5, 10, TimeUnit.SECONDS)) {
// 4. 再次查询数据库,避免并发修改
order = orderRepository.findById(orderId).orElse(null);
if (order != null && OrderStatus.PENDING_PAYMENT.equals(order.getStatus())) {
// 5. 执行取消逻辑
cancelOrder(order);
}
}
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}
/**
* 实际取消订单逻辑
*/
private void cancelOrder(Order order) {
// 1. 库存回滚
inventoryService.rollbackStock(order.getProductId(), order.getQuantity());
// 2. 更新订单状态
order.setStatus(OrderStatus.CANCELLED_TIMEOUT);
orderRepository.save(order);
// 3. 发送取消通知
notificationService.sendOrderCancelledNotification(order);
log.info("订单超时取消成功,订单ID: {}", order.getId());
}
/**
* 定时扫库任务(兜底机制)
*/
@Scheduled(fixedDelay = 300000) // 5分钟执行一次
public void scanAndCancelTimeoutOrders() {
// 查询超时未支付订单
List<Order> timeoutOrders = orderRepository
.findTimeoutOrders(OrderStatus.PENDING_PAYMENT, 30);
for (Order order : timeoutOrders) {
try {
cancelOrderIfNeeded(order.getId());
} catch (Exception e) {
log.error("扫库取消订单失败,订单ID: {}", order.getId(), e);
}
}
}
}
2. Redis + 消息中间件 + 数据库协同架构
核心实现代码示例:
@Service
@Slf4j
public class OrderCancelCoordinator {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private LocalMessageRepository localMessageRepository;
/**
* 取消订单并发送库存回滚消息
*/
@Transactional
public void cancelOrderAndNotifyRollback(Order order) {
// 1. 更新订单状态
order.setStatus(OrderStatus.CANCELLED);
orderRepository.save(order);
// 2. 保存本地消息
LocalMessage localMessage = new LocalMessage();
localMessage.setBusinessId(order.getId());
localMessage.setType(MessageType.INVENTORY_ROLLBACK);
localMessage.setContent(buildRollbackMessage(order));
localMessage.setStatus(MessageStatus.PENDING);
localMessageRepository.save(localMessage);
// 3. 发送消息到MQ
try {
rabbitTemplate.convertAndSend(
"order.cancel.exchange",
"order.cancel.rollback",
buildRollbackMessage(order)
);
// 4. 更新本地消息状态
localMessage.setStatus(MessageStatus.SENT);
localMessageRepository.save(localMessage);
} catch (Exception e) {
log.error("发送库存回滚消息失败", e);
// 事务会回滚,本地消息不会被保存
throw e;
}
}
/**
* 库存服务消费消息
*/
@RabbitListener(queues = "inventory.rollback.queue")
@Transactional
public void consumeRollbackMessage(InventoryRollbackMessage message) {
String messageId = message.getMessageId();
// 1. 幂等性校验
if (processedMessageRepository.existsByMessageId(messageId)) {
log.info("消息已处理,跳过: {}", messageId);
return;
}
// 2. 查询数据库当前状态
Inventory inventory = inventoryRepository
.findByProductId(message.getProductId());
// 3. 校验是否需要回滚
if (needRollback(inventory, message)) {
// 4. 执行库存回滚
inventory.setStock(inventory.getStock() + message.getQuantity());
inventoryRepository.save(inventory);
// 5. 记录处理过的消息
ProcessedMessage processed = new ProcessedMessage();
processed.setMessageId(messageId);
processed.setProcessedTime(new Date());
processedMessageRepository.save(processed);
log.info("库存回滚成功,产品ID: {}, 数量: {}",
message.getProductId(), message.getQuantity());
} else {
log.warn("库存状态异常,跳过回滚: {}", message.getProductId());
}
}
/**
* 消息重发定时任务
*/
@Scheduled(fixedDelay = 60000) // 1分钟执行一次
public void resendFailedMessages() {
// 查询未发送成功的消息
List<LocalMessage> failedMessages = localMessageRepository
.findByStatus(MessageStatus.PENDING);
for (LocalMessage message : failedMessages) {
try {
resendMessage(message);
} catch (Exception e) {
log.error("重发消息失败: {}", message.getId(), e);
}
}
}
}
3. 突发消息堆积全维度解决方案
核心实现代码示例:
@Configuration
@Slf4j
public class MessageQueueEmergencyConfig {
/**
* 应急扩容消费者配置
*/
@Bean
public SimpleRabbitListenerContainerFactory emergencyContainerFactory(
ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
// 动态调整并发消费者数量
factory.setConcurrentConsumers(5);
factory.setMaxConcurrentConsumers(20);
// 开启批量消费
factory.setBatchListener(true);
factory.setBatchSize(100);
factory.setConsumerBatchEnabled(true);
// 设置预取数量
factory.setPrefetchCount(100);
return factory;
}
/**
* 生产端限流配置
*/
@Bean
public RabbitTemplate throttledRabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
// 配置限流
template.setChannelTransacted(true);
// 添加拦截器,监控发送频率
template.setBeforePublishPostProcessors(new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
// 检查当前发送频率
if (isRateLimitExceeded()) {
log.warn("生产端限流触发,延迟发送");
throw new AmqpException("Rate limit exceeded");
}
return message;
}
});
return template;
}
/**
* 消费端降级处理
*/
@Component
public class DegradedMessageConsumer {
@RabbitListener(queues = "order.queue")
public void handleOrderMessage(OrderMessage message) {
// 1. 核心逻辑处理
processCoreBusiness(message);
// 2. 非核心逻辑异步处理
if (!isEmergencyMode()) {
processNonCoreBusiness(message);
} else {
// 紧急模式下,只处理核心逻辑
log.info("紧急模式,跳过非核心逻辑处理");
// 记录需要后续补偿处理
compensationService.recordForLaterProcess(message);
}
}
private void processCoreBusiness(OrderMessage message) {
// 核心业务处理
orderService.updateOrderStatus(message);
}
private void processNonCoreBusiness(OrderMessage message) {
// 非核心业务处理
statisticService.updateOrderStats(message);
notificationService.sendOrderNotification(message);
}
}
/**
* 消息堆积监控和自动扩容
*/
@Component
public class QueueMonitor {
@Autowired
private RabbitAdmin rabbitAdmin;
@Scheduled(fixedDelay = 30000) // 30秒监控一次
public void monitorAndScale() {
QueueInformation queueInfo = rabbitAdmin.getQueueInfo("order.queue");
if (queueInfo != null) {
int messageCount = queueInfo.getMessageCount();
int consumerCount = queueInfo.getConsumerCount();
log.info("队列监控 - 消息数: {}, 消费者数: {}", messageCount, consumerCount);
// 自动扩容逻辑
if (messageCount > 1000 && consumerCount < 10) {
scaleConsumers(consumerCount + 2);
}
// 自动缩容逻辑
if (messageCount < 100 && consumerCount > 3) {
scaleConsumers(consumerCount - 1);
}
}
}
private void scaleConsumers(int targetCount) {
log.info("调整消费者数量到: {}", targetCount);
// 实际实现中,这里应该调用K8s API或Docker API来调整容器数量
}
}
}
二、数据库事务深度解析
1. 事务隔离级别与问题对比
事务隔离级别实战代码示例:
@Service
@Slf4j
public class TransactionIsolationDemo {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 脏读演示
* 隔离级别:READ_UNCOMMITTED
*/
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void demonstrateDirtyRead() {
// 事务A:更新数据但未提交
jdbcTemplate.update("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
// 事务B:在事务A提交前读取数据
Integer balance = jdbcTemplate.queryForObject(
"SELECT balance FROM accounts WHERE id = 1", Integer.class);
log.info("事务B读取到未提交的数据: {}", balance);
// 事务A回滚
throw new RuntimeException("模拟事务A回滚");
}
/**
* 不可重复读演示
* 隔离级别:READ_COMMITTED
*/
public void demonstrateNonRepeatableRead() {
// 第一次读取
Integer balance1 = jdbcTemplate.queryForObject(
"SELECT balance FROM accounts WHERE id = 1", Integer.class);
log.info("第一次读取: {}", balance1);
// 另一个事务修改数据并提交
new Thread(() -> {
jdbcTemplate.update("UPDATE accounts SET balance = balance + 100 WHERE id = 1");
}).start();
// 等待另一个事务提交
try { Thread.sleep(100); } catch (InterruptedException e) {}
// 第二次读取(结果不同)
Integer balance2 = jdbcTemplate.queryForObject(
"SELECT balance FROM accounts WHERE id = 1", Integer.class);
log.info("第二次读取: {}", balance2);
}
/**
* 幻读演示
* 隔离级别:REPEATABLE_READ
*/
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void demonstratePhantomRead() {
// 第一次查询
Integer count1 = jdbcTemplate.queryForObject(
"SELECT COUNT(*) FROM orders WHERE user_id = 1", Integer.class);
log.info("第一次查询订单数: {}", count1);
// 另一个事务插入新订单并提交
new Thread(() -> {
jdbcTemplate.update("INSERT INTO orders(user_id, amount) VALUES (1, 100)");
}).start();
// 等待插入完成
try { Thread.sleep(100); } catch (InterruptedException e) {}
// 第二次查询(数量增加)
Integer count2 = jdbcTemplate.queryForObject(
"SELECT COUNT(*) FROM orders WHERE user_id = 1", Integer.class);
log.info("第二次查询订单数: {}", count2);
}
/**
* 不同隔离级别的实战选择
*/
@Service
public class IsolationLevelChooser {
// 1. 账户余额查询 - READ_COMMITTED
@Transactional(isolation = Isolation.READ_COMMITTED)
public Integer getAccountBalance(Long accountId) {
return jdbcTemplate.queryForObject(
"SELECT balance FROM accounts WHERE id = ?",
Integer.class, accountId);
}
// 2. 对账业务 - REPEATABLE_READ
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void reconciliation(Long userId) {
// 需要保证查询期间数据不变
List<Transaction> transactions = getTransactions(userId);
BigDecimal total = calculateTotal(transactions);
// 比对账户余额
BigDecimal balance = getBalance(userId);
if (!total.equals(balance)) {
throw new ReconciliationException("对账不平");
}
}
// 3. 资金转账 - SERIALIZABLE
@Transactional(isolation = Isolation.SERIALIZABLE)
public void transfer(Long fromAccountId, Long toAccountId, BigDecimal amount) {
// 强一致性要求高的场景
deductBalance(fromAccountId, amount);
addBalance(toAccountId, amount);
recordTransaction(fromAccountId, toAccountId, amount);
}
}
}
2. 事务传播机制实战应用
事务传播机制实战代码示例:
@Service
@Slf4j
public class TransactionPropagationDemo {
@Autowired
private UserService userService;
@Autowired
private OrderService orderService;
@Autowired
private LogService logService;
/**
* SUPPORTS演示 - 订单查询
*/
@Transactional(propagation = Propagation.REQUIRED)
public OrderDTO getOrderWithUserInfo(Long orderId) {
// 1. 查询订单(在事务中)
Order order = orderService.getOrder(orderId);
// 2. 查询用户信息(SUPPORTS - 复用事务)
User user = userService.getUserSupports(order.getUserId());
// 3. 返回组合数据
return combineOrderAndUser(order, user);
}
@Service
class UserService {
@Transactional(propagation = Propagation.SUPPORTS)
public User getUserSupports(Long userId) {
// 如果有事务就加入,没有事务就非事务执行
return userRepository.findById(userId).orElse(null);
}
// 单独查询用户(无事务)
public User getUserWithoutTransaction(Long userId) {
return getUserSupports(userId);
}
}
/**
* NOT_SUPPORTED演示 - 报表生成
*/
@Transactional(propagation = Propagation.REQUIRED)
public void generateReportAndUpdateStats(Long userId) {
// 1. 更新用户统计数据(在事务中)
userStatisticService.updateUserStats(userId);
try {
// 2. 生成报表(NOT_SUPPORTED - 暂停事务)
reportService.generateUserReport(userId);
} catch (Exception e) {
log.error("报表生成失败,但不影响主事务", e);
}
// 3. 继续其他业务逻辑(恢复事务)
notificationService.notifyUser(userId);
}
@Service
class ReportService {
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void generateUserReport(Long userId) {
// 暂停外部事务,避免长时间占用连接
long startTime = System.currentTimeMillis();
// 复杂报表生成逻辑
List<Order> orders = orderRepository.findByUserId(userId);
List<Payment> payments = paymentRepository.findByUserId(userId);
// ... 大量数据处理
// 生成PDF报表
generatePdfReport(orders, payments);
long costTime = System.currentTimeMillis() - startTime;
log.info("报表生成完成,耗时: {}ms", costTime);
}
}
/**
* NEVER演示 - 日志清理
*/
@Transactional(propagation = Propagation.REQUIRED)
public void processOrderAndCleanLogs(OrderDTO orderDTO) {
// 1. 处理订单(在事务中)
Order order = processOrder(orderDTO);
try {
// 2. 清理旧日志(NEVER - 禁止在事务中执行)
logService.cleanOldLogs(order.getUserId());
} catch (Exception e) {
log.error("日志清理失败,但订单处理不受影响", e);
}
// 3. 发送通知
notificationService.sendOrderCreatedNotification(order);
}
@Service
class LogService {
@Transactional(propagation = Propagation.NEVER)
public void cleanOldLogs(Long userId) {
// 如果调用方有事务,这里会抛出异常
Date thirtyDaysAgo = Date.from(
Instant.now().minus(30, ChronoUnit.DAYS));
int deletedCount = logRepository.deleteByUserIdAndCreateTimeBefore(
userId, thirtyDaysAgo);
log.info("清理了{}条旧日志", deletedCount);
// 如果这里在事务中,回滚会导致清理操作被撤销
}
/**
* 正确的调用方式
*/
public void safeCleanOldLogs(Long userId) {
// 在新的事务中执行
new Thread(() -> {
try {
cleanOldLogs(userId);
} catch (Exception e) {
log.error("异步清理日志失败", e);
}
}).start();
}
}
/**
* 不同传播行为的实战选择总结
*/
@Component
public class PropagationBestPractice {
// 1. 查询类服务 - SUPPORTS
@Transactional(propagation = Propagation.SUPPORTS)
public DataDTO queryData(Long id) {
// 查询操作,有没有事务都能执行
return dataRepository.findById(id);
}
// 2. 耗时操作 - NOT_SUPPORTED
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void timeConsumingOperation() {
// 大数据处理、文件操作等耗时操作
processLargeData();
generateReport();
}
// 3. 独立业务 - REQUIRES_NEW
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void independentBusiness() {
// 日志记录、消息发送等独立业务
auditService.recordOperation();
messageService.sendNotification();
}
// 4. 敏感操作 - NEVER
@Transactional(propagation = Propagation.NEVER)
public void sensitiveOperation() {
// 文件清理、缓存清除等敏感操作
fileService.cleanTempFiles();
cacheService.clearAllCaches();
}
}
}
三、Spring AOP与事务深度解析
1. Spring AOP代理机制与增强范围
AOP代理实战代码示例:
@Service
@Slf4j
public class AopProxyDemo {
/**
* 接口定义
*/
public interface UserService {
void publicMethod();
default void defaultMethod() {
privateMethod();
}
private void privateMethod() {
log.info("私有方法执行");
}
}
/**
* 实现类
*/
@Service
public class UserServiceImpl implements UserService {
@Override
public void publicMethod() {
log.info("public方法执行");
privateMethod(); // 内部调用
}
private void privateMethod() {
log.info("private方法执行");
}
protected void protectedMethod() {
log.info("protected方法执行");
}
void packagePrivateMethod() {
log.info("包私有方法执行");
}
}
/**
* 切面配置
*/
@Aspect
@Component
public class LoggingAspect {
// 只能切public方法
@Pointcut("execution(public * com.example.service.*.*(..))")
public void publicMethods() {}
@Before("publicMethods()")
public void logBefore(JoinPoint joinPoint) {
log.info("方法执行前: {}", joinPoint.getSignature().getName());
}
// 尝试切private方法(不会生效)
@Pointcut("execution(private * com.example.service.*.*(..))")
public void privateMethods() {} // 这个切入点不会匹配任何方法
}
/**
* 测试AOP代理
*/
@Test
public void testAopProxy() {
// 1. 测试public方法(会被增强)
userService.publicMethod();
// 输出:
// 方法执行前: publicMethod
// public方法执行
// 2. 测试private方法(不会被增强)
// 无法直接调用privateMethod
// 3. 测试自调用问题
userService.publicMethod(); // 会调用privateMethod
// privateMethod的调用不会经过代理,因此不会被切面增强
}
/**
* 解决自调用AOP失效问题
*/
@Service
public class UserServiceFixed {
@Autowired
private ApplicationContext applicationContext;
public void publicMethod() {
log.info("public方法执行");
// 错误方式:直接调用,不会触发AOP
// privateMethod();
// 正确方式:通过代理对象调用
getSelf().privateMethod();
}
private void privateMethod() {
log.info("private方法执行");
}
// 获取当前bean的代理对象
private UserServiceFixed getSelf() {
return applicationContext.getBean(UserServiceFixed.class);
}
}
/**
* 使用AspectJ编译时织入(增强private方法)
*/
@Configuration
@EnableLoadTimeWeaving
public class AspectJConfig {
// 需要额外的AspectJ依赖和配置
// 可以增强private方法,但配置复杂,一般不使用
}
}
2. @Transactional注解最佳实践
@Transactional最佳实践代码示例:
/**
* 错误的用法 - 注解在接口上
*/
public interface OrderService {
@Transactional // ❌ 不推荐放在接口上
OrderDTO createOrder(OrderRequest request);
@Transactional(readOnly = true) // ❌
OrderDTO getOrder(Long orderId);
}
@Service
class OrderServiceImpl implements OrderService {
@Override
public OrderDTO createOrder(OrderRequest request) {
// 实现逻辑
return processOrder(request);
}
@Override
public OrderDTO getOrder(Long orderId) {
return orderRepository.findById(orderId);
}
}
/**
* 正确的用法 - 注解在实现类上
*/
public interface OrderService {
OrderDTO createOrder(OrderRequest request); // 接口不写注解
OrderDTO getOrder(Long orderId);
}
@Service
class OrderServiceImpl implements OrderService {
@Override
@Transactional // ✅ 推荐放在实现类方法上
public OrderDTO createOrder(OrderRequest request) {
// 事务逻辑
Order order = createOrderInTransaction(request);
updateInventory(order);
processPayment(order);
return convertToDTO(order);
}
@Override
@Transactional(readOnly = true) // ✅
public OrderDTO getOrder(Long orderId) {
return orderRepository.findById(orderId);
}
/**
* 事务配置最佳实践
*/
@Transactional(
// 1. 指定回滚异常
rollbackFor = {Exception.class, BusinessException.class},
noRollbackFor = {ValidationException.class},
// 2. 指定传播行为
propagation = Propagation.REQUIRED,
// 3. 指定隔离级别
isolation = Isolation.READ_COMMITTED,
// 4. 设置超时时间
timeout = 30,
// 5. 是否只读
readOnly = false
)
public OrderDTO createOrderWithFullConfig(OrderRequest request) {
// 完整的事务配置
return processOrderWithTransaction(request);
}
/**
* 不同场景的事务配置示例
*/
// 1. 写操作 - 完整事务保护
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
timeout = 30,
rollbackFor = Exception.class
)
public void updateOrder(Order order) {
orderRepository.save(order);
// 其他写操作...
}
// 2. 读操作 - 只读事务
@Transactional(
propagation = Propagation.SUPPORTS,
readOnly = true
)
public OrderDTO queryOrder(Long orderId) {
return orderRepository.findById(orderId);
}
// 3. 批量操作 - 新事务
@Transactional(
propagation = Propagation.REQUIRES_NEW,
timeout = 60
)
public void batchProcessOrders(List<Order> orders) {
for (Order order : orders) {
processSingleOrder(order);
}
}
// 4. 日志记录 - 不参与事务
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void auditOrderOperation(Order order) {
auditRepository.save(createAuditLog(order));
}
/**
* 事务失效场景及解决方案
*/
@Service
class TransactionInvalidScenarios {
// 场景1: 非public方法
@Transactional // ❌ 不会生效
private void privateMethod() {
// 事务不会开启
}
// 场景2: 自调用
@Transactional
public void methodA() {
methodB(); // ❌ 自调用,事务不会生效
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {
// 会在methodA的事务中执行,而不是新事务
}
// 解决方案:通过代理对象调用
@Autowired
private ApplicationContext context;
@Transactional
public void methodAFixed() {
getSelf().methodB(); // ✅ 通过代理对象调用
}
private TransactionInvalidScenarios getSelf() {
return context.getBean(TransactionInvalidScenarios.class);
}
// 场景3: 异常被捕获
@Transactional
public void methodC() {
try {
riskyOperation(); // 可能抛异常
} catch (Exception e) {
// ❌ 异常被捕获,事务不会回滚
log.error("操作失败", e);
}
}
// 解决方案1: 重新抛出异常
@Transactional
public void methodCFixed1() {
try {
riskyOperation();
} catch (Exception e) {
log.error("操作失败", e);
throw e; // ✅ 重新抛出
}
}
// 解决方案2: 手动回滚
@Transactional
public void methodCFixed2() {
try {
riskyOperation();
} catch (Exception e) {
log.error("操作失败", e);
TransactionAspectSupport.currentTransactionStatus()
.setRollbackOnly(); // ✅ 手动回滚
}
}
}
}
四、SpringBoot自动配置与版本演进
1. SpringBoot自动配置核心机制
自动配置源码解析示例:
/**
* 1. @SpringBootApplication组合注解
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
})
public @interface SpringBootApplication {
// ... 属性定义
}
/**
* 2. 自定义Starter自动配置示例
*/
// 自动配置类
@Configuration
@ConditionalOnClass(DataSource.class) // 条件1: 类路径有DataSource
@ConditionalOnProperty(prefix = "my.datasource", name = "url") // 条件2: 配置了url
@EnableConfigurationProperties(MyDataSourceProperties.class) // 绑定配置属性
@AutoConfigureAfter(DataSourceAutoConfiguration.class) // 在官方配置后执行
public class MyDataSourceAutoConfiguration {
@Bean
@ConditionalOnMissingBean // 条件3: 容器中没有DataSource bean
public DataSource dataSource(MyDataSourceProperties properties) {
// 根据配置创建DataSource
HikariConfig config = new HikariConfig();
config.setJdbcUrl(properties.getUrl());
config.setUsername(properties.getUsername());
config.setPassword(properties.getPassword());
return new HikariDataSource(config);
}
@Bean
@ConditionalOnBean(DataSource.class) // 条件4: 有DataSource bean
@ConditionalOnMissingBean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
// 配置属性类
@ConfigurationProperties(prefix = "my.datasource")
public class MyDataSourceProperties {
private String url;
private String username;
private String password;
// getters/setters
}
// META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
// 包含: com.example.MyDataSourceAutoConfiguration
/**
* 3. 条件注解深度解析
*/
@Configuration
public class ConditionalDemo {
// 1. 类条件
@ConditionalOnClass(name = "com.example.SomeClass")
@Bean
public SomeService someService() {
return new SomeService();
}
// 2. Bean条件
@ConditionalOnMissingBean(DataSource.class)
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().build();
}
// 3. 属性条件
@ConditionalOnProperty(prefix = "app", name = "mode", havingValue = "prod")
@Bean
public ProductionService productionService() {
return new ProductionService();
}
// 4. 资源条件
@ConditionalOnResource(resources = "classpath:config.properties")
@Bean
public ConfigService configService() {
return new ConfigService();
}
// 5. Web应用条件
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@Bean
public ServletWebService servletWebService() {
return new ServletWebService();
}
// 6. 自定义条件
@Conditional(OnKubernetesCondition.class)
@Bean
public KubernetesService kubernetesService() {
return new KubernetesService();
}
}
// 自定义条件
public class OnKubernetesCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();
return env.containsProperty("KUBERNETES_SERVICE_HOST") &&
env.containsProperty("KUBERNETES_SERVICE_PORT");
}
}
2. SpringBoot版本演进与技术选型
版本特性对比与迁移指南:
/**
* SpringBoot各版本特性对比
*/
public class SpringBootVersionComparison {
/**
* 1. SpringBoot 1.0 特性示例
*/
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SpringBoot1Demo {
// 1.x 的配置方式
}
/**
* 2. SpringBoot 2.0 新特性
*/
@Configuration
public class SpringBoot2Features {
// 2.1 WebFlux响应式支持
@Bean
public RouterFunction<ServerResponse> routes() {
return RouterFunctions.route(
RequestPredicates.GET("/hello"),
request -> ServerResponse.ok()
.bodyValue("Hello WebFlux!")
);
}
// 2.2 Actuator 2.0
// 访问: /actuator/health, /actuator/metrics
// 2.3 Kotlin支持
// 可以使用Kotlin编写SpringBoot应用
}
/**
* 3. SpringBoot 3.0 迁移指南
*/
public class SpringBoot3Migration {
// 3.1 Java版本要求
// 必须使用Java 17+
// 3.2 Jakarta EE迁移
// 从javax.* 迁移到 jakarta.*
// import javax.servlet.http.HttpServlet; -> import jakarta.servlet.http.HttpServlet;
// 3.3 配置变更
@Configuration
public class ConfigChanges {
// server.tomcat.accesslog.enabled=true
// 变为: server.tomcat.accesslog.enabled=true
// 移除了一些废弃的配置
}
// 3.4 原生镜像支持
// pom.xml添加:
/*
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
*/
}
/**
* 4. SpringBoot 4.0 新特性
*/
public class SpringBoot4Features {
// 4.1 虚拟线程支持
@Bean
public TaskExecutor virtualThreadExecutor() {
return new SimpleAsyncTaskExecutor("virtual-") {
@Override
protected void doExecute(Runnable task) {
Thread.ofVirtual().start(task);
}
};
}
// 4.2 增强的AOT支持
@Configuration(proxyBeanMethods = false) // 优化AOT编译
public class AotOptimizedConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
// 4.3 改进的Observability
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCustomizer() {
return registry -> registry.config()
.commonTags("region", "us-east-1")
.commonTags("zone", "1a");
}
}
/**
* 技术选型建议
*/
public class TechnologySelection {
// 1. 新项目
public void newProject() {
// 推荐: SpringBoot 3.x + Java 17+
// 原因: 长期支持版本,现代化特性
}
// 2. 老项目升级
public void legacyProjectUpgrade() {
// 步骤1: 升级到SpringBoot 2.7.x (LTS)
// 步骤2: 迁移到Java 11/17
// 步骤3: 升级到SpringBoot 3.x
// 注意: 逐步升级,充分测试
}
// 3. 性能敏感项目
public void performanceSensitiveProject() {
// 推荐: SpringBoot 3.x + GraalVM Native Image
// 优势: 启动快,内存占用小
}
// 4. 云原生项目
public void cloudNativeProject() {
// 推荐: SpringBoot 3.x + Kubernetes
// 使用: Spring Cloud 2022.x+
}
}
/**
* 版本兼容性矩阵
*/
public class CompatibilityMatrix {
/*
SpringBoot 版本 | Java 版本 | Spring 版本 | 长期支持
--------------|----------|-----------|--------
2.7.x | 8-19 | 5.3.x | 是 (2025-11)
3.0.x | 17-20 | 6.0.x | 是 (2025-11)
3.1.x | 17-21 | 6.0.x | 是 (2025-11)
3.2.x | 17-21 | 6.1.x | 是 (2026-11)
4.0.x | 17-22 | 6.1.x | 是 (2026-11)
*/
}
}
五、核心总结与最佳实践
1. 分布式系统一致性保障最佳实践
/**
* 分布式系统一致性模式总结
*/
public class DistributedConsistencyPatterns {
/**
* 模式1: 最终一致性 + 补偿机制
*/
public class EventualConsistencyWithCompensation {
// 适用场景: 电商订单、库存管理
// 核心: 本地消息表 + 消息队列 + 补偿任务
public void processOrder(Order order) {
// 1. 本地事务更新订单
updateOrderLocal(order);
// 2. 记录本地消息
recordLocalMessage(order);
// 3. 异步发送消息
asyncSendMessage(order);
// 4. 定时补偿
scheduleCompensation(order);
}
}
/**
* 模式2: TCC分布式事务
*/
public class TccPattern {
// 适用场景: 资金交易、积分兑换
// 核心: Try-Confirm-Cancel 三阶段
@Transactional
public void transfer(TransferRequest request) {
// Try阶段: 资源预留
boolean tryResult = tryReserveResources(request);
if (tryResult) {
try {
// Confirm阶段: 确认提交
confirmOperation(request);
} catch (Exception e) {
// Cancel阶段: 回滚补偿
cancelOperation(request);
throw e;
}
}
}
}
/**
* 模式3: Saga长事务
*/
public class SagaPattern {
// 适用场景: 旅行预订、复杂业务流程
// 核心: 拆分事务 + 补偿操作
public void bookTravel(TravelRequest request) {
// 正向操作序列
bookFlight(request);
bookHotel(request);
bookCar(request);
// 补偿操作序列
// cancelCar() -> cancelHotel() -> cancelFlight()
}
}
}
2. 事务管理最佳实践清单
/**
* 事务管理最佳实践
*/
public class TransactionBestPractices {
/**
* 实践1: 合理选择隔离级别
*/
public class IsolationLevelPractice {
// 1. 读多写少: READ_COMMITTED
// 2. 财务系统: REPEATABLE_READ
// 3. 报表统计: READ_UNCOMMITTED
// 4. 资金交易: SERIALIZABLE
}
/**
* 实践2: 正确使用传播行为
*/
public class PropagationPractice {
// 1. 主业务: REQUIRED
// 2. 日志记录: REQUIRES_NEW
// 3. 查询操作: SUPPORTS
// 4. 耗时操作: NOT_SUPPORTED
// 5. 敏感操作: NEVER
}
/**
* 实践3: 事务失效预防
*/
public class TransactionInvalidPrevention {
// 1. 注解加在public方法
// 2. 避免自调用
// 3. 正确处理异常
// 4. 配置rollbackFor
// 5. 避免长时间事务
}
/**
* 实践4: 性能优化
*/
public class TransactionPerformance {
// 1. 缩短事务时间
// 2. 减少锁竞争
// 3. 使用只读事务
// 4. 合理设置超时
// 5. 避免大事务
}
}
3. SpringBoot项目架构建议
/**
* SpringBoot现代化架构
*/
@SpringBootApplication
public class ModernSpringBootApplication {
/**
* 分层架构
*/
// controller/ - 控制器层
// service/ - 服务层
// repository/ - 数据访问层
// domain/ - 领域模型
// config/ - 配置类
// exception/ - 异常处理
// dto/ - 数据传输对象
// utils/ - 工具类
/**
* 配置管理
*/
@Configuration
@Profile("dev")
public class DevConfig {
// 开发环境配置
}
@Configuration
@Profile("prod")
public class ProdConfig {
// 生产环境配置
}
/**
* 监控与可观测性
*/
@Configuration
public class ObservabilityConfig {
// 1. Actuator端点
// 2. Prometheus指标
// 3. 链路追踪
// 4. 健康检查
// 5. 日志聚合
}
/**
* 安全配置
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig {
// 1. 认证授权
// 2. CSRF防护
// 3. CORS配置
// 4. 安全头
// 5. 权限控制
}
/**
* 缓存配置
*/
@Configuration
@EnableCaching
public class CacheConfig {
// 1. Redis缓存
// 2. 本地缓存
// 3. 缓存注解
// 4. 缓存策略
}
}
总结
本次技术交流深入探讨了分布式系统、数据库事务、Spring AOP及SpringBoot等核心技术,形成了以下核心认知:
- 分布式一致性:以数据库为基准,结合中间件特性,通过状态校验、重试机制实现最终一致性
- 事务管理:理解隔离级别和传播机制的本质,根据业务场景合理选择配置
- Spring AOP:掌握动态代理机制,遵循最佳实践避免常见陷阱
- SpringBoot:理解自动配置原理,根据项目需求选择合适的版本和技术栈
- 学习之道:从实际问题出发理解技术演进,实现理论与实践的结合
这些知识点不仅是面试高频考点,更是生产环境中的必备技能。建议在实际项目中灵活应用,不断积累实战经验。
4493



被折叠的 条评论
为什么被折叠?



