Spring Boot进阶:安全、缓存与消息
Spring Boot进阶:安全、缓存与消息
概述
Spring Boot提供了丰富的功能模块。本教程介绍安全、缓存和消息队列的使用。
1. Spring Security
import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.*;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public UserDetailsService userDetailsService() {
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder().encode("password"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder().encode("admin"))
.roles("USER", "ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
2. Spring Cache
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;
@Service
@CacheConfig(cacheNames = "users")
public class UserService {
@Cacheable(key = "#id")
public User findById(Long id) {
// 模拟数据库查询
System.out.println("从数据库查询用户: " + id);
return new User(id, "Alice", 25);
}
@CachePut(key = "#user.id")
public User save(User user) {
System.out.println("保存用户: " + user.getId());
return user;
}
@CacheEvict(key = "#id")
public void deleteById(Long id) {
System.out.println("删除用户: " + id);
}
@CacheEvict(allEntries = true)
public void clearCache() {
System.out.println("清除所有缓存");
}
}
3. Spring Messaging
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();
}
}
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
@Controller
public class WebSocketController {
@MessageMapping("/chat")
@SendTo("/topic/messages")
public ChatMessage sendMessage(ChatMessage message) {
return message;
}
}
4. 实际应用示例
JWT认证
import io.jsonwebtoken.*;
import org.springframework.stereotype.Component;
@Component
public class JwtTokenProvider {
private String jwtSecret = "secret";
private long jwtExpiration = 86400000;
public String generateToken(Long userId, String username) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + jwtExpiration);
return Jwts.builder()
.setSubject(Long.toString(userId))
.claim("username", username)
.setIssuedAt(now)
.setExpiration(expiryDate)
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
public Long getUserIdFromToken(String token) {
Claims claims = Jwts.parser()
.setSigningKey(jwtSecret)
.parseClaimsJws(token)
.getBody();
return Long.parseLong(claims.getSubject());
}
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
return false;
}
}
}
5. 最佳实践
- 使用Spring Security:保护应用安全
- 使用Spring Cache:提高应用性能
- 使用消息队列:实现异步处理
- 使用WebSocket:实现实时通信
- 监控应用状态:使用Spring Boot Actuator
总结
Spring Boot提供了丰富的功能模块。掌握安全、缓存和消息队列的使用,可以构建更强大、更安全的企业级应用。