Spring Boot 项目各模块整合

第一部分:整合 Spring Security


✅ 第一步:添加依赖

Maven(pom.xml

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Gradle(build.gradle

复制代码
implementation 'org.springframework.boot:spring-boot-starter-security'

💡 只需这一行!无需额外配置即可启用基础安全。


✅ 第二步:启动项目,查看效果

  1. 启动应用(如 java -jar 或 IDE 运行)

  2. 访问任意接口(如 http://localhost:8080/

  3. 会被重定向到登录页:/login

  4. 控制台会打印一行日志:

    复制代码
    Using generated security password: abc123-def456-ghi789
    • 用户名:user
    • 密码:控制台打印的随机字符串

⚠️ 这是 开发阶段的临时机制,生产环境必须自定义用户和权限!


✅ 第三步:自定义安全配置(推荐)

创建一个配置类,继承 WebSecurityConfigurerAdapter仅适用于 Spring Boot 2.x

但在 Spring Boot 3.x + Spring Security 6+ 中,不再推荐继承该类 ,而是使用 Lambda DSL 配置方式

🟢 Spring Boot 3.x(推荐写法)

复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    // 定义用户(内存中)
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("123456")
            .roles("USER", "ADMIN")
            .build();

        return new InMemoryUserDetailsManager(user);
    }

    // 安全过滤链配置
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()      // 公开路径
                .requestMatchers("/admin/**").hasRole("ADMIN")  // 需 ADMIN 角色
                .anyRequest().authenticated()                   // 其他请求需登录
            )
            .formLogin(form -> form
                .loginPage("/login")        // 自定义登录页(可选)
                .permitAll()
            )
            .logout(logout -> logout
                .permitAll()
            );

        return http.build();
    }
}

🔴 Spring Boot 2.x(旧写法,不适用于 SB3)

复制代码
@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().permitAll()
            .and()
            .logout().permitAll();
    }

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("123456")
            .roles("USER", "ADMIN")
            .build();
        return new InMemoryUserDetailsManager(user);
    }
}

重点区别 :SB3 使用 SecurityFilterChain + Lambda,不再继承 WebSecurityConfigurerAdapter


✅ 第四步:配合 JWT / 数据库(进阶)

场景 1:使用数据库存储用户(推荐生产环境)

复制代码
@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserEntity user = userRepository.findByUsername(username);
        if (user == null) throw new UsernameNotFoundException("User not found");
        
        return org.springframework.security.core.userdetails.User
            .withUsername(user.getUsername())
            .password(user.getPassword()) // 必须是 BCrypt 加密后的
            .roles(user.getRoles().toArray(new String[0]))
            .build();
    }
}

然后在 SecurityConfig 中注入:

复制代码
@Bean
public UserDetailsService userDetailsService() {
    return new CustomUserDetailsService();
}

🔐 密码必须用 BCryptPasswordEncoder 加密:

复制代码
@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

场景 2:前后端分离 + JWT(无 Session)

需要禁用 CSRF 和 Session:

复制代码
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .csrf(csrf -> csrf.disable()) // 前后端分离通常关闭 CSRF
        .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/api/auth/login").permitAll()
            .anyRequest().authenticated()
        )
        .addFilterBefore(jwtFilter(), UsernamePasswordAuthenticationFilter.class); // 自定义 JWT Filter

    return http.build();
}

✅ 常见注解(方法级安全)

在 Service 或 Controller 方法上加权限控制:

复制代码
@EnableMethodSecurity // SB3 启用方法级安全(替代 @EnableGlobalMethodSecurity)
@SpringBootApplication
public class Application { ... }

@Service
public class OrderService {

    @PreAuthorize("hasRole('ADMIN')")
    public void deleteOrder(Long id) {
        // 只有 ADMIN 能删除
    }

    @PostAuthorize("returnObject.owner == authentication.name")
    public Order getOrder(Long id) {
        // 返回后检查
    }
}

✅ 总结:整合步骤清单

步骤 操作
1️⃣ 添加 spring-boot-starter-security 依赖
2️⃣ (可选)创建 SecurityConfig 配置类
3️⃣ 定义用户来源(内存 / 数据库 / LDAP)
4️⃣ 配置 URL 权限规则(公开 / 登录 / 角色)
5️⃣ (生产)使用 BCryptPasswordEncoder 加密密码
6️⃣ (可选)启用方法级安全 @PreAuthorize

🚫 注意事项

  • Spring Boot 3.x 不再支持 WebSecurityConfigurerAdapter

  • 默认开启 CSRF 防护,前后端分离项目需手动关闭

  • 密码不能明文存储,必须加密(推荐 BCrypt)

  • 开发时可通过 application.properties 临时关闭安全(不推荐):

    复制代码
    # ❌ 仅测试用!
    spring.security.user.name=admin
    spring.security.user.password=123456

第二部分:整合 Nacos

步骤 1: 添加依赖

首先,在你的 Spring Boot 项目的 pom.xml 文件中添加 Nacos 的依赖。你需要添加 spring-cloud-starter-alibaba-nacos-discovery 用于服务注册和发现,如果需要使用 Nacos 进行配置管理,则还需要添加 spring-cloud-starter-alibaba-nacos-config

复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!-- 如果需要配置管理 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

确保你已经在项目中引入了 Spring Cloud 相关依赖,并且版本兼容。

步骤 2: 配置 Nacos

application.ymlapplication.properties 中添加 Nacos 相关配置。

对于服务注册和发现:

复制代码
spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # Nacos服务器地址

对于配置管理(如果使用):

复制代码
spring:
  cloud:
    nacos:
      config:
        server-addr: localhost:8848 # Nacos服务器地址
        file-extension: yaml # 配置内容的数据格式

步骤 3: 启用 Nacos Discovery

在 Spring Boot 应用的主类上添加 @EnableDiscoveryClient 注解来启用服务发现功能。

复制代码
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDiscoveryClient
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

步骤 4: 测试整合结果

启动你的 Spring Boot 应用后,你可以通过访问 Nacos 控制台(默认地址是 http://localhost:8848/nacos),登录后检查服务是否已经成功注册到 Nacos。

以上就是将 Spring Boot 项目与 Nacos 整合的基本步骤。根据实际需求,你可能还需要进行一些额外的配置或调整。例如,如果你的应用部署在多个环境(开发、测试、生产等),你可能需要为每个环境配置不同的 Nacos 地址或者使用不同的命名空间等。

第三部分:整合 Elasticsearch

✅ 完整整合指南(Spring Boot 3.x + Elasticsearch 8.x)

1️⃣ 添加依赖(Maven)

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

💡 这个 starter 会自动引入:

  • org.springframework.data:spring-data-elasticsearch
  • co.elastic.clients:elasticsearch-java(官方客户端)

2️⃣ 配置 Elasticsearch 连接(application.yml

复制代码
spring:
  elasticsearch:
    uris: http://localhost:9200  # Elasticsearch 服务器地址
    # 如果启用安全认证(默认开启)
    # username: elastic
    # password: your-elastic-password

3️⃣ 定义实体类(Document)

复制代码
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

@Document(indexName = "products") // 索引名(ES中相当于数据库表)
public class Product {

    @Id  // ES _id 字段
    private String id;

    @Field(type = FieldType.Text, analyzer = "ik_max_word") // 支持中文分词
    private String name;

    @Field(type = FieldType.Keyword) // 精确匹配
    private String category;

    @Field(type = FieldType.Double)
    private Double price;

    @Field(type = FieldType.Date)
    private java.time.LocalDateTime createTime;

    // getter/setter/constructor...
}

4️⃣ 创建 Repository(数据访问层)

复制代码
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductRepository extends ElasticsearchRepository<Product, String> {
    
    // 自动提供 save(), findById(), delete(), findAll() 等方法
    
    // 方法名查询
    List<Product> findByCategory(String category);
    List<Product> findByNameContaining(String name);
}

5️⃣ Service 层使用示例

复制代码
@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    public Product save(Product product) {
        product.setCreateTime(LocalDateTime.now());
        return productRepository.save(product);
    }

    public Page<Product> searchByCategory(String category, Pageable pageable) {
        return productRepository.findByCategory(category, pageable);
    }
}

6️⃣ Controller 示例

复制代码
@RestController
@RequestMapping("/api/products")
public class ProductController {

    @Autowired
    private ProductService productService;

    @PostMapping
    public Product create(@RequestBody Product product) {
        return productService.save(product);
    }

    @GetMapping("/search")
    public Page<Product> search(
        @RequestParam String category,
        @RequestParam(defaultValue = "0") int page,
        @RequestParam(defaultValue = "10") int size) {
        
        Pageable pageable = PageRequest.of(page, size);
        return productService.searchByCategory(category, pageable);
    }
}

7️⃣ 启动类配置

复制代码
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

🔧 高级配置选项

连接集群(生产环境)

复制代码
spring:
  elasticsearch:
    uris:
      - http://es-node1:9200
      - http://es-node2:9200
      - http://es-node3:9200
    username: elastic
    password: your-password

自定义客户端配置

复制代码
@Configuration
public class ElasticsearchConfig {

    @Bean
    public ElasticsearchRestTemplate elasticsearchRestTemplate(
            ElasticsearchClient elasticsearchClient) {
        return new ElasticsearchRestTemplate(elasticsearchClient);
    }
}

🧪 快速测试

  1. 启动 Elasticsearch(Docker):

    docker run -d --name elasticsearch -p 9200:9200 -e "discovery.type=single-node" elasticsearch:8.9.0

  2. 启动 Spring Boot 应用

  3. 插入测试数据:

    curl -X POST http://localhost:8080/api/products
    -H "Content-Type: application/json"
    -d '{"name":"iPhone 15","category":"Electronics","price":999.99}'


⚠️ 常见问题

问题 解决方案
Connection refused 检查 ES 是否启动:curl http://localhost:9200
No qualifying bean 确认启动类有 @SpringBootApplication
中文搜索乱码 安装 IK 分词器:elasticsearch-plugin install analysis-ik

📊 功能对比

功能 Spring Data Elasticsearch 原生 ES Client
CRUD 操作 ✅ 自动 Repository ❌ 需手动编写
分页查询 ✅ Pageable 支持 ❌ 需手动实现
注解映射 @Document @Field ❌ JSON 字符串
配置管理 application.yml ❌ 代码配置

总结 :使用 spring-boot-starter-data-elasticsearch 可以让你快速集成 Elasticsearch,享受 Spring Boot 的自动配置和 Spring Data 的便捷 API,是构建搜索功能的最佳选择!

如果你需要更具体的配置(如中文分词、聚合查询、索引模板等),也可以继续问我!

相关推荐
eggrall1 小时前
Linux 基础开发工具 —— 解锁高效开发的底层密钥
linux·运维·服务器
weixin_307779131 小时前
基于AWS安全组的两层架构访问控制设计与实现
运维·云原生·架构·云计算·aws
全栈工程师修炼指南1 小时前
Nginx | 负载均衡策略:ip_hash / hash 会话保持实践
运维·tcp/ip·nginx·负载均衡·哈希算法
哇哈哈&1 小时前
rabbitmq最简单的安装方法
linux·运维·centos
虎头金猫1 小时前
从杂乱到有序,Paperless-ngx 加个cpolar更好用
linux·运维·人工智能·docker·开源·beautifulsoup·pandas
源之缘-OFD先行者2 小时前
定制化 Live555 实战:按需开发低耗 RTSP 服务器,完美适配 C# 项目
运维·服务器·c#
wifi chicken2 小时前
Linux Wlan无线网络开发之DHCP预留功能 实操demo
linux·运维·服务器
段帅龙呀2 小时前
服务器因BIOS设置导致无法正常做RAID修复
运维·服务器·raid
人工智能训练2 小时前
openEuler系统中home文件夹下huawei、HwHiAiUser、lost+found 文件夹的区别和作用
linux·运维·服务器·人工智能·windows·华为·openeuler