亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java使用Spring AI的10個(gè)實(shí)用技巧分享

 更新時(shí)間:2025年06月10日 10:34:54   作者:程序員岳焱  
在當(dāng)今的軟件開(kāi)發(fā)領(lǐng)域,人工智能的集成已經(jīng)成為提升應(yīng)用功能和用戶(hù)體驗(yàn)的重要手段,對(duì)于 Java 開(kāi)發(fā)者而言,Spring AI 提供了一套強(qiáng)大且便捷的工具,本文將深入探討 Java 使用 Spring AI 的 10 個(gè)實(shí)用技巧,感興趣的小伙伴跟著小編一起來(lái)看看吧

引言

在當(dāng)今的軟件開(kāi)發(fā)領(lǐng)域,人工智能的集成已經(jīng)成為提升應(yīng)用功能和用戶(hù)體驗(yàn)的重要手段。對(duì)于 Java 開(kāi)發(fā)者而言,Spring AI 提供了一套強(qiáng)大且便捷的工具,使得在 Java 項(xiàng)目中集成 AI 功能變得更加輕松。本文將深入探討 Java 使用 Spring AI 的 10 個(gè)實(shí)用技巧,幫助開(kāi)發(fā)者充分發(fā)揮 Spring AI 的潛力,打造出更加智能、高效的應(yīng)用程序。

技巧 1:使用 @EnableSpringAI 注解快速啟動(dòng)

在 Spring Boot 應(yīng)用中,快速啟動(dòng) Spring AI 的配置可以通過(guò)@EnableSpringAI注解輕松實(shí)現(xiàn)。這個(gè)注解會(huì)自動(dòng)觸發(fā)一系列 AI 相關(guān)的配置,極大地簡(jiǎn)化了我們的工作。

首先,在項(xiàng)目的依賴(lài)中引入 Spring AI 相關(guān)的庫(kù)。如果使用 Maven,在pom.xml文件中添加如下依賴(lài):

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter</artifactId>
    <version>1.0.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-deepseek</artifactId>
    <version>1.0.0</version>
</dependency>

然后,在 Spring Boot 的主應(yīng)用類(lèi)上添加@EnableSpringAI注解:

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

通過(guò)上述簡(jiǎn)單操作,Spring 會(huì)自動(dòng)掃描并配置 AI 相關(guān)的 Bean,我們無(wú)需手動(dòng)編寫(xiě)大量繁瑣的配置代碼,即可快速開(kāi)啟 Spring AI 之旅。

技巧 2:通過(guò) AiClient 接口注入不同提供商的客戶(hù)端

Spring AI 的AiClient接口是一個(gè)強(qiáng)大的抽象,它允許我們輕松地集成不同的 AI 服務(wù)提供商,如 DeepSeek 等。

application.yml中添加 DeepSeek 客戶(hù)端的配置:

spring:
  ai:
    deepseek:
      api-key: your_deepseek_api_key
      base-url: https://api.deepseek.com/v1

然后,創(chuàng)建一個(gè)配置類(lèi)來(lái)注入DeepSeekClient

@Configuration
public class AiClientConfig {
    @Bean
    public DeepSeekClient deepSeekClient(DeepSeekClientProperties properties) {
        return new DeepSeekClient(properties.getApiKey());
    }
}

這樣,在其他組件中,我們就可以通過(guò)依賴(lài)注入的方式使用DeepSeekClient了:

@Service
public class MyAiService {
    private final DeepSeekClient deepSeekClient;

    public MyAiService(DeepSeekClient deepSeekClient) {
        this.deepSeekClient = deepSeekClient;
    }

    public String generateText(String prompt) {
        // 使用DeepSeekClient進(jìn)行文本生成
        return deepSeekClient.generate(prompt).getGeneratedText();
    }
}

通過(guò)這種方式,我們可以根據(jù)項(xiàng)目需求輕松切換不同的 AI 服務(wù)提供商,而無(wú)需對(duì)業(yè)務(wù)邏輯進(jìn)行大規(guī)模修改。

技巧 3:使用 PromptTemplate 分離業(yè)務(wù)邏輯和提示詞

在使用 AI 進(jìn)行文本生成等任務(wù)時(shí),提示詞的管理至關(guān)重要。PromptTemplate允許我們將業(yè)務(wù)邏輯與提示詞分離,提高代碼的可維護(hù)性和復(fù)用性。

假設(shè)我們有一個(gè)簡(jiǎn)單的文本總結(jié)需求,定義一個(gè)提示詞模板:

public class SummaryService {
    private static final String SUMMARY_TEMPLATE = "請(qǐng)總結(jié)以下內(nèi)容:{text}";

    public String summarizeText(String text) {
        PromptTemplate promptTemplate = new PromptTemplate(SUMMARY_TEMPLATE);
        // 使用模板生成具體的提示詞
        String prompt = promptTemplate.render("text", text);
        // 這里假設(shè)已經(jīng)有一個(gè)AiClient實(shí)例用于生成文本
        String summary = aiClient.generate(prompt).getGeneratedText();
        return summary;
    }
}

在上述代碼中,SUMMARY_TEMPLATE定義了提示詞的結(jié)構(gòu),{text}是一個(gè)占位符。通過(guò)render方法,我們將實(shí)際的文本內(nèi)容填充到占位符中,生成最終的提示詞。這樣,當(dāng)我們需要修改提示詞的格式或邏輯時(shí),只需在SUMMARY_TEMPLATE中進(jìn)行調(diào)整,而不會(huì)影響到業(yè)務(wù)邏輯代碼。

技巧 4:實(shí)現(xiàn) MessageConverter 處理復(fù)雜數(shù)據(jù)格式

在實(shí)際應(yīng)用中,我們可能需要處理各種復(fù)雜的數(shù)據(jù)格式,如 JSON、XML 等。Spring AI 的MessageConverter接口可以幫助我們實(shí)現(xiàn)數(shù)據(jù)格式的轉(zhuǎn)換,以便更好地與 AI 模型交互。

以 JSON 格式為例,我們定義一個(gè)自定義的MessageConverter來(lái)將 JSON 字符串轉(zhuǎn)換為 AI 模型所需的Message對(duì)象:

@Component
public class JsonMessageConverter implements MessageConverter {
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public Message toMessage(String json) {
        try {
            // 假設(shè)JSON結(jié)構(gòu)中有一個(gè)"content"字段表示用戶(hù)輸入
            JsonInput jsonInput = objectMapper.readValue(json, JsonInput.class);
            return new UserMessage(jsonInput.getContent());
        } catch (Exception e) {
            throw new RuntimeException("Failed to convert JSON to Message", e);
        }
    }

    @Override
    public String fromMessage(Message message) {
        try {
            JsonOutput jsonOutput = new JsonOutput(message.getContent());
            return objectMapper.writeValueAsString(jsonOutput);
        } catch (Exception e) {
            throw new RuntimeException("Failed to convert Message to JSON", e);
        }
    }

    private static class JsonInput {
        private String content;

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }

    private static class JsonOutput {
        private String result;

        public JsonOutput(String result) {
            this.result = result;
        }

        public String getResult() {
            return result;
        }
    }
}

在上述代碼中,toMessage方法將 JSON 字符串解析為UserMessage對(duì)象,fromMessage方法則將Message對(duì)象轉(zhuǎn)換回 JSON 格式。這樣,我們可以在與 AI 模型交互時(shí),方便地處理 JSON 數(shù)據(jù),確保數(shù)據(jù)格式的兼容性。

技巧 5:集成 Spring Security 保護(hù) AI 接口

當(dāng)我們將 AI 功能暴露為接口供外部使用時(shí),安全保護(hù)是必不可少的。Spring Security 可以幫助我們輕松實(shí)現(xiàn)對(duì) AI 接口的安全防護(hù)。

首先,添加 Spring Security 的依賴(lài):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

然后,創(chuàng)建一個(gè) Spring Security 配置類(lèi):

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
           .csrf().disable()
           .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
           .and()
           .authorizeRequests()
                .antMatchers("/ai/**").authenticated()
                .anyRequest().permitAll()
           .and()
           .addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
        return new JwtAuthenticationFilter();
    }
}

在上述配置中,我們禁用了 CSRF 保護(hù)(因?yàn)樵跓o(wú)狀態(tài)的 API 場(chǎng)景中通常不需要),設(shè)置了會(huì)話創(chuàng)建策略為無(wú)狀態(tài),并且配置了對(duì)/ai/**路徑下的請(qǐng)求進(jìn)行身份驗(yàn)證。JwtAuthenticationFilter是一個(gè)自定義的過(guò)濾器,用于處理 JWT 認(rèn)證,具體實(shí)現(xiàn)如下:

public class JwtAuthenticationFilter extends OncePerRequestFilter {
    private static final String HEADER_STRING = "Authorization";
    private static final String TOKEN_PREFIX = "Bearer ";

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String header = request.getHeader(HEADER_STRING);
        if (header == null ||!header.startsWith(TOKEN_PREFIX)) {
            filterChain.doFilter(request, response);
            return;
        }
        String token = header.replace(TOKEN_PREFIX, "");
        Claims claims = Jwts.parser().setSigningKey("your_secret_key").parseClaimsJws(token).getBody();
        String username = claims.getSubject();
        List<String> roles = (List<String>) claims.get("roles");
        List<SimpleGrantedAuthority> authorities = roles.stream()
               .map(SimpleGrantedAuthority::new)
               .collect(Collectors.toList());
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, null, authorities);
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        filterChain.doFilter(request, response);
    }
}

通過(guò)上述配置和過(guò)濾器,我們實(shí)現(xiàn)了基于 JWT 的身份驗(yàn)證,確保只有經(jīng)過(guò)授權(quán)的用戶(hù)才能訪問(wèn) AI 接口,保障了系統(tǒng)的安全性。

技巧 6:使用 AiFunction 注解暴露 Java 方法給 AI 模型

AiFunction注解是 Spring AI 提供的一個(gè)強(qiáng)大功能,它允許我們將 Java 方法暴露為 AI 模型可以調(diào)用的函數(shù)。這在很多場(chǎng)景下非常有用,比如讓 AI 模型根據(jù)業(yè)務(wù)需求調(diào)用特定的 Java 邏輯。

假設(shè)我們有一個(gè)計(jì)算商品折扣價(jià)格的 Java 方法,我們可以使用AiFunction注解將其暴露:

@Component
public class DiscountService {
    @AiFunction(
        name = "calculateDiscountPrice",
        description = "計(jì)算商品的折扣價(jià)格,輸入商品原價(jià)和折扣率,返回折扣后的價(jià)格"
    )
    public double calculateDiscountPrice(double originalPrice, double discountRate) {
        return originalPrice * (1 - discountRate);
    }
}

在上述代碼中,@AiFunction注解指定了函數(shù)的名稱(chēng)和描述。這樣,AI 模型在需要計(jì)算折扣價(jià)格時(shí),就可以通過(guò)調(diào)用calculateDiscountPrice函數(shù)來(lái)實(shí)現(xiàn)。

技巧 7:配置 AiClientProperties 調(diào)整連接超時(shí)和重試策略

為了優(yōu)化 AI 客戶(hù)端與服務(wù)提供商之間的交互性能,我們可以通過(guò)配置AiClientProperties來(lái)調(diào)整連接超時(shí)和重試策略。

application.yml中添加如下配置:

spring:
  ai:
    deepseek:
      client:
        connection-timeout: 5000
        read-timeout: 10000
        max-retries: 3

上述配置中,spring.ai.deepseek.client.connection-timeout設(shè)置了連接超時(shí)時(shí)間為 5 秒,spring.ai.deepseek.client.read-timeout設(shè)置了讀取超時(shí)時(shí)間為 10 秒,spring.ai.deepseek.client.max-retries設(shè)置了最大重試次數(shù)為 3 次。

在代碼中,我們可以通過(guò)注入DeepSeekClientProperties來(lái)獲取這些配置并應(yīng)用到DeepSeekClient中:

@Configuration
public class DeepSeekClientConfig {
    @Bean
    public DeepSeekClient deepSeekClient(DeepSeekClientProperties properties) {
        DeepSeekClient client = new DeepSeekClient(properties.getApiKey());
        client.setConnectionTimeout(properties.getConnectionTimeout());
        client.setReadTimeout(properties.getReadTimeout());
        client.setMaxRetries(properties.getMaxRetries());
        return client;
    }
}

通過(guò)合理配置連接超時(shí)和重試策略,可以提高 AI 客戶(hù)端在網(wǎng)絡(luò)不穩(wěn)定等情況下的可靠性和性能。

技巧 8:使用 ReactiveAiClient 實(shí)現(xiàn)非阻塞請(qǐng)求處理

在高并發(fā)的應(yīng)用場(chǎng)景中,使用響應(yīng)式編程模型可以顯著提高系統(tǒng)的性能和資源利用率。Spring AI 提供的ReactiveAiClient接口允許我們以非阻塞的方式處理 AI 請(qǐng)求。

假設(shè)我們有一個(gè)需要調(diào)用 AI 模型生成文本的服務(wù),使用ReactiveAiClient可以這樣實(shí)現(xiàn):

@Service
public class ReactiveAiTextGenerationService {
    private final ReactiveDeepSeekClient reactiveDeepSeekClient;

    public ReactiveAiTextGenerationService(ReactiveDeepSeekClient reactiveDeepSeekClient) {
        this.reactiveDeepSeekClient = reactiveDeepSeekClient;
    }

    public Mono<String> generateText(String promptText) {
        Prompt prompt = new Prompt(new UserMessage(promptText));
        return reactiveDeepSeekClient.generate(prompt)
               .map(response -> response.getGeneratedText());
    }
}

在上述代碼中,generateText方法返回一個(gè)Mono<String>,表示一個(gè)異步的文本生成操作。通過(guò)這種方式,我們可以在不阻塞線程的情況下處理大量的 AI 請(qǐng)求,提高系統(tǒng)的吞吐量和響應(yīng)速度。

技巧 9:通過(guò) AiMessageHistory 維護(hù)多輪對(duì)話上下文

在涉及多輪對(duì)話的場(chǎng)景中,如聊天機(jī)器人,維護(hù)對(duì)話上下文非常重要。Spring AI 的AiMessageHistory可以幫助我們輕松實(shí)現(xiàn)這一點(diǎn)。

創(chuàng)建一個(gè)服務(wù)類(lèi)來(lái)管理對(duì)話歷史:

@Service
public class ChatService {
    private final AiMessageHistory messageHistory;
    private final DeepSeekClient deepSeekClient;

    public ChatService(DeepSeekClient deepSeekClient, AiMessageHistory messageHistory) {
        this.deepSeekClient = deepSeekClient;
        this.messageHistory = messageHistory;
    }

    public String chat(String userInput) {
        UserMessage userMessage = new UserMessage(userInput);
        messageHistory.addMessage(userMessage);
        String response = deepSeekClient.generate(messageHistory.getMessages()).getGeneratedText();
        AiMessage aiResponse = new AiMessage(response);
        messageHistory.addMessage(aiResponse);
        return response;
    }
}

在上述代碼中,每次用戶(hù)輸入消息時(shí),我們將其添加到messageHistory中,然后使用messageHistory中的所有消息與 AI 模型進(jìn)行交互,獲取 AI 的響應(yīng)后,再將響應(yīng)添加到messageHistory中。這樣,messageHistory始終維護(hù)著完整的對(duì)話上下文,使得 AI 模型能夠根據(jù)之前的對(duì)話內(nèi)容進(jìn)行更準(zhǔn)確的回復(fù)。

技巧 10:自定義 AiResponseHandler 處理大文本的分段生成

在處理大文本生成時(shí),一次性獲取全部文本可能會(huì)導(dǎo)致內(nèi)存問(wèn)題或長(zhǎng)時(shí)間等待。Spring AI 允許我們自定義AiResponseHandler來(lái)處理流式響應(yīng),實(shí)現(xiàn)大文本的分段生成。

首先,定義一個(gè)自定義的AiResponseHandler

public class CustomAiResponseHandler implements AiResponseHandler {
    private final List<String> partialTexts = new ArrayList<>();

    @Override
    public void handleResponse(AiResponse response) {
        String partialText = response.getGeneratedText();
        partialTexts.add(partialText);
        System.out.println("接收到分段文本: " + partialText);
    }

    public String getFullText() {
        return String.join("", partialTexts);
    }
}

在實(shí)際使用時(shí),我們可以將自定義的AiResponseHandlerReactiveAiClient結(jié)合,實(shí)現(xiàn)響應(yīng)式的流式文本生成處理:

@Service
public class StreamingTextGenerationService {
    private final ReactiveDeepSeekClient reactiveDeepSeekClient;

    public StreamingTextGenerationService(ReactiveDeepSeekClient reactiveDeepSeekClient) {
        this.reactiveDeepSeekClient = reactiveDeepSeekClient;
    }

    public Mono<Void> generateStreamingText(String promptText, CustomAiResponseHandler handler) {
        Prompt prompt = new Prompt(new UserMessage(promptText));
        return reactiveDeepSeekClient.generateStreaming(prompt)
                .doOnNext(handler::handleResponse)
                .then();
    }
}

generateStreamingText方法中,reactiveDeepSeekClient.generateStreaming發(fā)起流式文本生成請(qǐng)求,doOnNext操作會(huì)在每次接收到分段響應(yīng)時(shí)調(diào)用CustomAiResponseHandlerhandleResponse方法,最后通過(guò)then操作返回一個(gè)表示操作完成的Mono<Void>。

通過(guò)這種方式,我們可以有效處理大文本生成場(chǎng)景,避免一次性加載大量文本導(dǎo)致的內(nèi)存壓力,同時(shí)還能在文本生成過(guò)程中及時(shí)展示內(nèi)容,提升用戶(hù)體驗(yàn)。

總結(jié)

本文詳細(xì)介紹了 Java 使用 Spring AI 的 10 個(gè)實(shí)用技巧,從項(xiàng)目初始化到復(fù)雜場(chǎng)景優(yōu)化均有覆蓋。這些技巧涵蓋了 Spring AI 應(yīng)用開(kāi)發(fā)的全流程,無(wú)論是初涉 AI 開(kāi)發(fā)的新手,還是尋求技術(shù)突破的資深開(kāi)發(fā)者,都能從中獲取實(shí)用的技術(shù)方案。通過(guò)合理運(yùn)用這些技巧,Java 開(kāi)發(fā)者可以更高效地將 AI 能力融入項(xiàng)目,打造出功能強(qiáng)大、體驗(yàn)出色的智能應(yīng)用

以上就是Java使用Spring AI的10個(gè)實(shí)用技巧分享的詳細(xì)內(nèi)容,更多關(guān)于Java使用Spring AI的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java應(yīng)用程序的CPU使用率飆升原因詳細(xì)分析

    Java應(yīng)用程序的CPU使用率飆升原因詳細(xì)分析

    這篇文章主要介紹了Java應(yīng)用程序的CPU使用率飆升原因詳細(xì)分析,在 Java 中,我們使用 JVM 進(jìn)行線程調(diào)度,所以一般來(lái)說(shuō),線程的調(diào)度有兩種模式:分時(shí)調(diào)度和搶占式調(diào)度,線程和進(jìn)程在阻塞或者等待時(shí),都不會(huì)使用 CPU 資源,需要的朋友可以參考下
    2024-01-01
  • SpringBoot @Test單元測(cè)試方式

    SpringBoot @Test單元測(cè)試方式

    這篇文章主要介紹了SpringBoot @Test單元測(cè)試方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Jenkins Maven pom jar打包未拉取最新包解決辦法

    Jenkins Maven pom jar打包未拉取最新包解決辦法

    包版本號(hào)未變更新后,jenkins打包不會(huì)拉取最新包,本文主要介紹了Jenkins Maven pom jar打包未拉取最新包解決辦法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • 關(guān)于slf4j_log4j2源碼學(xué)習(xí)心得

    關(guān)于slf4j_log4j2源碼學(xué)習(xí)心得

    這篇文章主要介紹了slf4j_log4j2源碼學(xué)習(xí)心得,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 輕松掌握java裝飾者模式

    輕松掌握java裝飾者模式

    這篇文章主要幫助大家輕松掌握java裝飾者模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Spring源碼解析之事務(wù)傳播特性

    Spring源碼解析之事務(wù)傳播特性

    今天帶大家分析Spring源碼,文中對(duì)Spring事務(wù)傳播特性做了非常詳細(xì)的介紹及代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05
  • MyBatis入門(mén)實(shí)例教程之創(chuàng)建一個(gè)簡(jiǎn)單的程序

    MyBatis入門(mén)實(shí)例教程之創(chuàng)建一個(gè)簡(jiǎn)單的程序

    這篇文章主要介紹了MyBatis入門(mén)創(chuàng)建一個(gè)簡(jiǎn)單的程序,在?MySQL?中創(chuàng)建數(shù)據(jù)庫(kù)?mybatisdemo,編碼為?utf8,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • Java設(shè)計(jì)模式之java橋接模式詳解

    Java設(shè)計(jì)模式之java橋接模式詳解

    這篇文章主要介紹了Java設(shè)計(jì)模式之橋接模式,結(jié)合實(shí)例形式詳細(xì)分析了橋接模式的概念、功能、Java實(shí)現(xiàn)方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2021-09-09
  • 詳解Java MD5二次加密的應(yīng)用

    詳解Java MD5二次加密的應(yīng)用

    MD5的全稱(chēng)是message-digest algorithm 5 信息-摘要算法。這篇文章主要為大家詳細(xì)介紹了Java中MD5二次加密的應(yīng)用,感興趣的小伙伴可以了解一下
    2023-02-02
  • Mybatis以main方法形式調(diào)用dao層執(zhí)行代碼實(shí)例

    Mybatis以main方法形式調(diào)用dao層執(zhí)行代碼實(shí)例

    這篇文章主要介紹了Mybatis以main方法形式調(diào)用dao層執(zhí)行代碼實(shí)例,MyBatis 是一款優(yōu)秀的持久層框架,MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作,需要的朋友可以參考下
    2023-08-08

最新評(píng)論