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,是构建搜索功能的最佳选择!

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

相关推荐
大树881 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠1 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质1 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工1 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智1 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_1 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉1 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造
AC赳赳老秦1 天前
用 OpenClaw 搭建服务器故障应急响应系统,自动处理 80% 常见运维故障
android·运维·服务器·python·rxjava·deepseek·openclaw
java_cj1 天前
深入kube-apiserver认证机制:从Bearer Token到mTLS的完整认证链解析
linux·运维·服务器·云原生·容器·kubernetes
lsyeei1 天前
linux 系统目录详解
linux·运维·服务器