Spring Boot进阶详解
Spring Boot Actuator
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: always
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
@Component
public class CustomHealthIndicator implements HealthIndicator {
@Override
public Health health() {
boolean serviceUp = checkService();
if (serviceUp) {
return Health.up().withDetail("service", "Running").build();
}
return Health.down().withDetail("service", "Not Running").build();
}
private boolean checkService() {
return true;
}
}
缓存配置
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.stereotype.Service;
@EnableCaching
@Service
public class CachedUserService {
@Cacheable(value = "users", key = "#id")
public User findById(Long id) {
simulateSlowService();
return userRepository.findById(id).orElse(null);
}
@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) {
return userRepository.save(user);
}
@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
消息队列集成
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
public static final String QUEUE_NAME = "myqueue";
public static final String EXCHANGE_NAME = "myexchange";
@Bean
public Queue myQueue() {
return new Queue(QUEUE_NAME, true);
}
@Bean
public TopicExchange myExchange() {
return new TopicExchange(EXCHANGE_NAME);
}
@Bean
public Binding binding(Queue myQueue, TopicExchange myExchange) {
return BindingBuilder.bind(myQueue).to(myExchange).with("myroutingkey");
}
}
@Service
public class MessageProducer {
private final RabbitTemplate rabbitTemplate;
public MessageProducer(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
public void sendMessage(String message) {
rabbitTemplate.convertAndSend("myexchange", "myroutingkey", message);
System.out.println("发送消息: " + message);
}
}
@Service
public class MessageConsumer {
@RabbitListener(queues = "myqueue")
public void receiveMessage(String message) {
System.out.println("接收消息: " + message);
}
}
定时任务
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@EnableScheduling
@EnableAsync
@Component
public class ScheduledTasks {
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
System.out.println("当前时间: " + java.time.LocalTime.now());
}
@Scheduled(cron = "0 0 12 * * ?")
public void dailyTask() {
System.out.println("每日定时任务执行");
}
@Async
public void asyncTask() {
System.out.println("异步任务执行,线程: " +
Thread.currentThread().getName());
}
}
WebSocket配置
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.*;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
}
@Controller
public class WebSocketController {
@MessageMapping("/chat")
@SendTo("/topic/messages")
public ChatMessage handleMessage(ChatMessage message) {
return message;
}
}
测试
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@MockBean
private UserRepository userRepository;
@Test
public void testFindById() {
User mockUser = new User(1L, "张三", "zhangsan@example.com");
when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser));
User user = userService.findById(1L);
assertNotNull(user);
assertEquals("张三", user.getName());
}
}
Spring Boot最佳实践
- 使用Actuator监控应用健康状态
- 合理配置缓存提高性能
- 使用消息队列解耦系统
- 利用定时任务处理周期性工作
- 编写单元测试保证代码质量
总结
Spring Boot进阶特性让你的应用更加健壮和高效。Actuator、缓存、消息队列等是构建企业级应用的重要工具。