Huong Dan Java https://huongdanjava.com/ Java development tutorials Sun, 11 Jan 2026 01:49:43 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://huongdanjava.com/wp-content/uploads/2018/01/favicon.png Huong Dan Java https://huongdanjava.com/ 32 32 Building an MCP Server using Spring AI MCP Server Starter https://huongdanjava.com/building-an-mcp-server-using-spring-ai-mcp-server-starter.html https://huongdanjava.com/building-an-mcp-server-using-spring-ai-mcp-server-starter.html#respond Sun, 11 Jan 2026 01:49:43 +0000 https://huongdanjava.com/?p=25024 I’ve introduced you to the Model Context Protocol (MCP), which allows LLM models to access data after the cut-off point or personal data using a common standard. There are many pre-built MCP servers available. If you want to build your own MCP server using Java,… Read More

The post Building an MCP Server using Spring AI MCP Server Starter appeared first on Huong Dan Java.

]]>
I’ve introduced you to the Model Context Protocol (MCP), which allows LLM models to access data after the cut-off point or personal data using a common standard. There are many pre-built MCP servers available. If you want to build your own MCP server using Java, you can use Spring AI MCP Server Starter. How exactly do you do this? Let’s find out together in this tutorial!

First, I’ll create a new Spring Boot project with the Model Context Protocol Server dependency as follows:

Spring AI MCP Server supports three transport mechanisms, including:

  • Standard Input/Output (STDIO): Simply put, this transport means the server communicates with the client using standard input (STDIN) and standard output (STDOUT) instead of sockets (TCP/UDP), HTTP, or other network protocols. This STDIO transport is suitable for applications using the command line or desktop applications.
  • Spring MVC (Server-Sent Events)
  • Spring WebFlux (Reactive SSE)

By default, it supports STDIO transport with the spring-ai-starter-mcp-server dependency, but if you want to use HTTP transport with Server-Sent Events, you can use the spring-ai-starter-mcp-server-webmvc dependency, or HTTP transport with Reactive Server-Sent Events, you can also use the spring-ai-starter-mcp-server-webflux dependency. For example, in this tutorial, I’ll be using the STDIO transport, so I’ll disable the web application type for my Spring Boot, using the spring.main.web-application-type property as follows:

spring.main.web-application-type=none

We’ll also need to disable the Spring Boot banner and console log because this information will be sent to the client if we leave it printed, using the following properties:

spring.main.banner-mode=off
logging.pattern.console=

There are two types of MCP servers we can build using Spring AI MCP Server: Synchronous Server and Asynchronous Server. A Synchronous server handles requests/responses synchronously, while an asynchronous server handles them non-blocking, asynchronously. You declare the type of MCP server you want to build using the property spring.ai.mcp.server.type with the value sync or async. For my example, I will implement a Synchronous server, so I will declare it as follows:

spring.ai.mcp.server.type=sync

Now I will build tools for my MCP server example.

To build tools using Spring AI MCP Server, you can declare a bean of a class with methods annotated with the @Tool annotation. For example:

package com.huongdanjava.springboot.springai;

import java.util.HashMap;
import java.util.Map;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service;

@Service
public class HuongDanJava {

  private Map<String, Integer> users = new HashMap<>();

  @Tool(name = "addUser", description = "Add a user with an age to the list. Need to specify user name and age of user")
  public String addUser(String name, int age) {
    users.put(name, age);

    return "Welcome, " + name;
  }

  @Tool(name = "getAge", description = "Base on the name in the input, return age of user")
  public String getAge(String name) {
    try {
      int age = users.get(name);

      return String.format("%s is %s years old", name, age);
    } catch (Exception e) {
      return "No user found!";
    }
  }
}

For this example, I’m exposing two tools: “addUser” and “getAge”!

For each tool, there’s a corresponding method:

  • With the @Tool annotation, you need to declare two attributes: name and description. The name attribute is used to register with the MCP Host, while the description helps the LLM models understand the tool’s purpose and select the correct tool based on the user’s prompt.
  • The method parameters will be passed the correct values ​​by the LLM models based on the user’s prompt. After processing the business logic, the method will return a result. The LLM models will use this result to return the user’s response in the most natural language possible.

After defining the tools, you need to expose them to the MCP client by declaring a bean for a list of ToolCallbacks, as follows:

@Bean
List<ToolCallback> toolCallbacks(HuongDanJava huongDanJava) {
  return List.of(ToolCallbacks.from(huongDanJava));
}

Now, I will build my MCP Server and use Claude Desktop to test the results.

You can reread the tutorial Introduction to Model Context Protocol to understand how to configure an MCP Server with Claude Desktop!

I will configure my MCP Server with Claude Desktop as follows:

{
  "mcpServers": {
    ...
    "huongdanjava": {
      "command": "/Users/khanhnguyenj/.sdkman/candidates/java/21.0.4-tem/bin/java",
      "args": [
        "-jar",
        "/Users/khanhnguyenj/Documents/code/huongdanjava.com/spring-boot-spring-ai-mcp-server/target/spring-boot-spring-ai-mcp-server-0.0.1-SNAPSHOT.jar"
      ]
    }
  }
}

The file /Users/khanhnguyenj/Documents/code/huongdanjava.com/spring-boot-spring-ai-mcp-server/target/spring-boot-spring-ai-mcp-server-0.0.1-SNAPSHOT.jar is the MCP server file that I built above!

After restarting Claude Desktop, you will see the list of tools included in Claude Desktop as follows:

Now you can use Claude Desktop to perform the tasks you want.

For example, I requested it to add some users with age information, and the result was as follows:

and then we retrieved the age information of these users, with the following results:

Perfect, right? Claude Desktop can record information and retrieve the information we want. It responded with results in very natural language.

The post Building an MCP Server using Spring AI MCP Server Starter appeared first on Huong Dan Java.

]]>
https://huongdanjava.com/building-an-mcp-server-using-spring-ai-mcp-server-starter.html/feed 0
New video: RESTful API Naming Conventions Explained | Best Practices for Clean API Design https://huongdanjava.com/new-video-restful-api-naming-conventions-explained-best-practices-for-clean-api-design.html https://huongdanjava.com/new-video-restful-api-naming-conventions-explained-best-practices-for-clean-api-design.html#respond Sat, 10 Jan 2026 08:30:26 +0000 https://huongdanjava.com/?p=25015 The post New video: RESTful API Naming Conventions Explained | Best Practices for Clean API Design appeared first on Huong Dan Java.

]]>

The post New video: RESTful API Naming Conventions Explained | Best Practices for Clean API Design appeared first on Huong Dan Java.

]]>
https://huongdanjava.com/new-video-restful-api-naming-conventions-explained-best-practices-for-clean-api-design.html/feed 0
New Video: Consume RESTful Web Services with RestClient | Spring Framework 7+ https://huongdanjava.com/new-video-consume-restful-web-services-with-restclient-spring-framework-7-2.html https://huongdanjava.com/new-video-consume-restful-web-services-with-restclient-spring-framework-7-2.html#respond Tue, 06 Jan 2026 01:27:27 +0000 https://huongdanjava.com/?p=25004 The post New Video: Consume RESTful Web Services with RestClient | Spring Framework 7+ appeared first on Huong Dan Java.

]]>

The post New Video: Consume RESTful Web Services with RestClient | Spring Framework 7+ appeared first on Huong Dan Java.

]]>
https://huongdanjava.com/new-video-consume-restful-web-services-with-restclient-spring-framework-7-2.html/feed 0
Introduction to Model Context Protocol https://huongdanjava.com/introduction-to-model-context-protocol.html https://huongdanjava.com/introduction-to-model-context-protocol.html#respond Sat, 03 Jan 2026 10:01:02 +0000 https://huongdanjava.com/?p=24989 Large Language Models (LLMs) or AI models like ChatGPT, Gemini, etc., are only trained on data up to a certain point in time, known as the cutoff point. For example, for ChatGPT at the time of writing this tutorial, its knowledge only extends to April… Read More

The post Introduction to Model Context Protocol appeared first on Huong Dan Java.

]]>
Large Language Models (LLMs) or AI models like ChatGPT, Gemini, etc., are only trained on data up to a certain point in time, known as the cutoff point. For example, for ChatGPT at the time of writing this tutorial, its knowledge only extends to April 2024:

Even Gemini only lasts until June 2024:

This means that ChatGPT and Gemini don’t have the information to respond to us after the cutoff point.

Another problem is that LLMs can’t respond to information related to our personal data, data on our machines, or other private content.

For LLMs to access private information or information after the cutoff point, the only way is for us to provide it.

We can provide information to LLMs, but the problem is that each LLM will have a different way of reading that information. How do we standardize them? That’s why the Model Context Protocol (MCP) concept was born! MCP was introduced by Anthropic, the father of AI models, Claude, defining a standard for AI models to access different data sources, thereby enabling them to respond to the information we want.

MCP General Architecture

To understand MCP, you need to grasp the following concepts:

  • MCP Hosts: These are client programs of AI models, used to access personal data or data after the cutoff point.
  • MCP Clients: Within the MCP Host, they connect to the MCP Server to retrieve information.
  • MCP Servers: These are applications that expose data from data sources to AI models using the Model Context Protocol.

The General Architecture of MCP can be redrawn as follows:

As you can see, for each data source, we have a corresponding MCP Server. MCP Server 1 and 2 expose data to the data sources on the local machine, while MCP Server 3 connects to a Remote Service to retrieve information and expose data to AI models according to the MCP standard.

Many ready-made MCP Servers are available here: https://github.com/modelcontextprotocol/servers?tab=readme-ov-file#-reference-servers.

Now, I will guide you on how to use a simple MCP server to understand how MCP servers work!

Configure the MCP Server with the MCP Host

The MCP Server I’ll be using for this example is the Filesystem at https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem. This MCP Server is written in Node.js!

The Filesystem MCP Server allows you to perform various tasks using the tools listed at https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem#tools. You can think of tools as features that we can use with the MCP Server.

The MCP Host I’ll be using is the Claude AI Desktop application.

To configure the MCP Server Filesystem with the Claude Desktop application as the MCP Host, open the Claude Desktop application, then go to the Settings menu. In the Settings window, select the Developer tab.

then click the Edit Config button. A claude_desktop_config.json file will open.

This claude_desktop_config.json file contains the definitions of all the MCP Servers for Claude Desktop! These MCP Servers will run every time we run Claude Desktop.

You can configure the Filesystem MCP Server in the claude_desktop_config.json file with the following content:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/khanhnguyenj/Documents/code/huongdanjava.com"
      ]
    }
  }
}

With this configuration, Claude Desktop will install the Filesystem MCP Server by running the Node.js eXecute (NPX) command to download the @modelcontextprotocol/server-filesystem package from https://www.npmjs.com/package/@modelcontextprotocol/server-filesystem. The directory “/Users/khanhnguyenj/Documents/code/huongdanjava.com” is the directory on your machine that will be used by the Filesystem MCP server to query information. You can add more directories if you wish.

After configuring the Filesystem MCP Server, restart Claude Desktop.

After restarting, you will see the Filesystem MCP Server included in Claude Desktop as follows:

Now, I just need to type the command “List out all folders” into the prompt. For example, Claude Desktop displays the following result:

As you can see, Claude Desktop uses the list_allowed_directories, directory_tree, and list_directory tools to list all the directories within the configured directory. A great feature is that it can categorize the directories based on the information they contain and provide a general overview of each directory.

Thus, the Filesystem MCP Server has enabled us to access information on our computer, something that Claude Desktop cannot do by default.

The post Introduction to Model Context Protocol appeared first on Huong Dan Java.

]]>
https://huongdanjava.com/introduction-to-model-context-protocol.html/feed 0
Naming convention for RESTful API specs https://huongdanjava.com/naming-convention-for-restful-api-specs.html https://huongdanjava.com/naming-convention-for-restful-api-specs.html#respond Tue, 16 Dec 2025 00:45:19 +0000 https://huongdanjava.com/?p=24781 When defining API specs for RESTful APIs, there are some naming conventions that are best practices that you should follow to make these API specs consistent, intuitive, and easy to maintain. These principles are as follows: Use nouns instead of verbs when naming resources Instead… Read More

The post Naming convention for RESTful API specs appeared first on Huong Dan Java.

]]>
When defining API specs for RESTful APIs, there are some naming conventions that are best practices that you should follow to make these API specs consistent, intuitive, and easy to maintain.

These principles are as follows:

  • Use nouns instead of verbs when naming resources

Instead of /getStudents, you should name /students

  • Use plural nouns for collections of resources, singular for a resource

Instead of /student, you should name /students for collections, /students/{id} for a resource.

  • Use the HTTP method to define actions
    • GET /students → Get list of students
    • GET /students/{id} → Get information of a student
    • POST /students → Add new student
    • PUT /students/{id} → Update student information
    • PATCH /students/{id} → Update partial of student information
    • DELETE /students/{id} → Delete information of a student
  • Use lowercase with hyphens; do not use camelCase or snake_case

Instead of /studentProfiles or /student_profiles, we should name it as /student-profiles

  • If your resources are related to each other, name them hierarchically with slashes

Instead of /getStudentSubjects to get subject information for students, you can name /students/{id}/subjects or /students/{id}/subjects/{id}

  • Use query parameters to filter, sort, paginate, search, …

For example: /students?classId=1A&sort=createdAt&limit=10&page=2

These are the basic principles. Please try to follow them!

The post Naming convention for RESTful API specs appeared first on Huong Dan Java.

]]>
https://huongdanjava.com/naming-convention-for-restful-api-specs.html/feed 0
Video: Spring 7 BeanRegistrar Explained: Register Beans Programmatically https://huongdanjava.com/video-spring-7-beanregistrar-explained-register-beans-programmatically-2.html https://huongdanjava.com/video-spring-7-beanregistrar-explained-register-beans-programmatically-2.html#respond Thu, 04 Dec 2025 14:14:38 +0000 https://huongdanjava.com/?p=24958 The post Video: Spring 7 BeanRegistrar Explained: Register Beans Programmatically appeared first on Huong Dan Java.

]]>

The post Video: Spring 7 BeanRegistrar Explained: Register Beans Programmatically appeared first on Huong Dan Java.

]]>
https://huongdanjava.com/video-spring-7-beanregistrar-explained-register-beans-programmatically-2.html/feed 0
Consume RESTful API using Spring Framework’s RestClient https://huongdanjava.com/consume-restful-api-using-spring-frameworks-restclient.html https://huongdanjava.com/consume-restful-api-using-spring-frameworks-restclient.html#respond Sat, 29 Nov 2025 04:05:27 +0000 https://huongdanjava.com/?p=24946 If your application uses Spring Framework 7 or later, you can now use the RestClient class to consume RESTful APIs. How exactly? Let’s find out in this tutorial! For example, I will create a new Spring Boot project version 4.0.0 or later, using the Web… Read More

The post Consume RESTful API using Spring Framework’s RestClient appeared first on Huong Dan Java.

]]>
If your application uses Spring Framework 7 or later, you can now use the RestClient class to consume RESTful APIs. How exactly? Let’s find out in this tutorial!

For example, I will create a new Spring Boot project version 4.0.0 or later, using the Web Starter dependency as follows:

I will consume 2 APIs that I have exposed in 2 tutorials about API Versioning using request header and path parameter, guys!

For example, to keep it simple, I will also use the CommandLineRunner class so that when running the Spring Boot application, it will call the 2 APIs above using the RestClient class.

You can initialize the RestClient class object with baseURL as follows:

package com.huongdanjava.springboot;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestClient;

@SpringBootApplication
public class SpringBootRestClientApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringBootRestClientApplication.class, args);
  }

  @Bean
  CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {
      RestClient restClient = RestClient.builder()
          .baseUrl("http://localhost:8080")
          .build();
    };
  }

}

Suppose the RESTful API you need to consume uses API Versioning, like the example in the tutorial API Versioning using request headers with Spring framework. In that case, you can use the ApiVersionInserter class to add version information, for example, as follows:

package com.huongdanjava.springboot;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.ApiVersionInserter;
import org.springframework.web.client.RestClient;

@SpringBootApplication
public class SpringBootRestClientApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringBootRestClientApplication.class, args);
  }

  @Bean
  CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {
      ApiVersionInserter apiVersionInserter = ApiVersionInserter.builder()
          .useHeader("X-Api-Version")
          .build();

      RestClient restClient = RestClient.builder()
          .baseUrl("http://localhost:8080")
          .apiVersionInserter(apiVersionInserter)
          .build();
    };
  }

}

Because the API in the tutorial API Versioning using request headers with Spring framework using headers for API versioning, you can use the useHeader() method of the ApiVersionInserter class to add header name information. The value of this header name will be declared when we call the “/hello” endpoint as follows:

package com.huongdanjava.springboot;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.web.client.ApiVersionInserter;
import org.springframework.web.client.RestClient;

@SpringBootApplication
public class SpringBootRestClientApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringBootRestClientApplication.class, args);
  }

  @Bean
  CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {
      ApiVersionInserter apiVersionInserter = ApiVersionInserter.builder()
          .useHeader("X-Api-Version")
          .build();

      RestClient restClient = RestClient.builder()
          .baseUrl("http://localhost:8080")
          .apiVersionInserter(apiVersionInserter)
          .build();

      String body = restClient.get()
          .uri("/hello")
          .accept(MediaType.APPLICATION_JSON)
          .apiVersion("1.0.0")
          .retrieve()
          .body(String.class);

      System.out.println(body);
    };
  }

}

As you can see, we use the apiVersion() method to pass the endpoint version information.

The result when you run this example is as follows:

If you request the API in the tutorial API Versioning using path parameter with Spring framework, you can use the usePathSegment() method of the ApiVersionInserter class to define a segment containing version information as follows:

package com.huongdanjava.springboot;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.web.client.ApiVersionInserter;
import org.springframework.web.client.RestClient;

@SpringBootApplication
public class SpringBootRestClientApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringBootRestClientApplication.class, args);
  }

  @Bean
  CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {
      ApiVersionInserter apiVersionInserter = ApiVersionInserter.builder()
          .usePathSegment(0)
          .build();

      RestClient restClient = RestClient.builder()
          .baseUrl("http://localhost:8080")
          .apiVersionInserter(apiVersionInserter)
          .build();

      String body = restClient.get()
          .uri("/hello")
          .accept(MediaType.APPLICATION_JSON)
          .apiVersion("v1.0.0")
          .retrieve()
          .body(String.class);

      System.out.println(body);
    };
  }

}

The result when I run this example is as follows:

The post Consume RESTful API using Spring Framework’s RestClient appeared first on Huong Dan Java.

]]>
https://huongdanjava.com/consume-restful-api-using-spring-frameworks-restclient.html/feed 0
Video: API Versioning with Path Parameters in Spring Framework 7 | Clean & Future-Proof REST APIs https://huongdanjava.com/video-api-versioning-with-path-parameters-in-spring-framework-7-clean-future-proof-rest-apis-2.html https://huongdanjava.com/video-api-versioning-with-path-parameters-in-spring-framework-7-clean-future-proof-rest-apis-2.html#respond Thu, 27 Nov 2025 01:54:03 +0000 https://huongdanjava.com/?p=24938 The post Video: API Versioning with Path Parameters in Spring Framework 7 | Clean & Future-Proof REST APIs appeared first on Huong Dan Java.

]]>

The post Video: API Versioning with Path Parameters in Spring Framework 7 | Clean & Future-Proof REST APIs appeared first on Huong Dan Java.

]]>
https://huongdanjava.com/video-api-versioning-with-path-parameters-in-spring-framework-7-clean-future-proof-rest-apis-2.html/feed 0
Registering beans in Spring container with BeanRegistrar https://huongdanjava.com/registering-beans-in-spring-container-with-beanregistrar.html https://huongdanjava.com/registering-beans-in-spring-container-with-beanregistrar.html#respond Wed, 26 Nov 2025 06:46:11 +0000 https://huongdanjava.com/?p=24925 Since version 7, Spring has introduced another way for us to register one or more beans at the same time in the Spring container using the implementation of the BeanRegistrar interface. How exactly? Let’s find out in this tutorial! I will create a Maven project:… Read More

The post Registering beans in Spring container with BeanRegistrar appeared first on Huong Dan Java.

]]>
Since version 7, Spring has introduced another way for us to register one or more beans at the same time in the Spring container using the implementation of the BeanRegistrar interface. How exactly? Let’s find out in this tutorial!

I will create a Maven project:

with Spring Framework dependency:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>7.0.1</version>
</dependency>

for example.

Suppose I have a Hello class like this:

package com.huongdanjava.spring;

public class Hello {

  public void say() {
    System.out.println("Hello World!");
  }
}

To register a bean for this Hello class using the implementation of the BeanRegistrar interface, you can override the register() method of the BeanRegistrar interface and use the registerBean() method of the BeanRegistry class as follows:

package com.huongdanjava.spring;

import org.springframework.beans.factory.BeanRegistrar;
import org.springframework.beans.factory.BeanRegistry;
import org.springframework.core.env.Environment;

public class HDJBeanRegistrar implements BeanRegistrar {

  @Override
  public void register(BeanRegistry registry, Environment env) {
    registry.registerBean(Hello.class);
  }
}

With the parameter of class Hello.class as above, Spring will automatically generate a unique bean name based on the class name and initialize the bean for class Hello in the Spring container.

You can assign the bean name you want, or you can also add conditions to initialize the bean for class Hello, for example, as follows:

package com.huongdanjava.spring;

import org.springframework.beans.factory.BeanRegistrar;
import org.springframework.beans.factory.BeanRegistry;
import org.springframework.core.env.Environment;

public class HDJBeanRegistrar implements BeanRegistrar {

  @Override
  public void register(BeanRegistry registry, Environment env) {
    registry.registerBean(Hello.class);
    
    registry.registerBean("huongdanjava_hello", Hello.class);
    
    if (env.matchesProfiles("dev")) {
      registry.registerBean("huongdanjava_hello_dev", Hello.class);
    }
  }
}

After implementing the BeanRegistrar interface, you can use the @Import annotation to declare this bean definition with the Spring container, as follows:

package com.huongdanjava.spring;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(HDJBeanRegistrar.class)
public class AppConfig {

}

Now you can get the bean of the Hello class and use it:

package com.huongdanjava.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Application {

  static void main() {
    ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    Hello hello = context.getBean("huongdanjava_hello", Hello.class);

    hello.say();
  }

}

My results are as follows:

The post Registering beans in Spring container with BeanRegistrar appeared first on Huong Dan Java.

]]>
https://huongdanjava.com/registering-beans-in-spring-container-with-beanregistrar.html/feed 0
Video: API Versioning with Request Headers in Spring Framework 7 — Best Practice Guide https://huongdanjava.com/video-api-versioning-with-request-headers-in-spring-framework-7-best-practice-guide-2.html https://huongdanjava.com/video-api-versioning-with-request-headers-in-spring-framework-7-best-practice-guide-2.html#respond Tue, 25 Nov 2025 22:47:48 +0000 https://huongdanjava.com/?p=24921 The post Video: API Versioning with Request Headers in Spring Framework 7 — Best Practice Guide appeared first on Huong Dan Java.

]]>

The post Video: API Versioning with Request Headers in Spring Framework 7 — Best Practice Guide appeared first on Huong Dan Java.

]]>
https://huongdanjava.com/video-api-versioning-with-request-headers-in-spring-framework-7-best-practice-guide-2.html/feed 0