<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Adam Tarcali</title>
    <description>The latest articles on DEV Community by Adam Tarcali (@tarcalia).</description>
    <link>https://dev.to/tarcalia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2254816%2F8a93a00c-793e-4d33-8d5d-1719fd51f49e.png</url>
      <title>DEV Community: Adam Tarcali</title>
      <link>https://dev.to/tarcalia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tarcalia"/>
    <language>en</language>
    <item>
      <title>Feign Clients with Multiple Interceptors in Spring Boot</title>
      <dc:creator>Adam Tarcali</dc:creator>
      <pubDate>Wed, 18 Jun 2025 09:02:13 +0000</pubDate>
      <link>https://dev.to/tarcalia/feign-clients-with-multiple-interceptors-in-spring-boot-hh2</link>
      <guid>https://dev.to/tarcalia/feign-clients-with-multiple-interceptors-in-spring-boot-hh2</guid>
      <description>&lt;p&gt;When working with Spring Boot and OpenFeign, it's quite common to add custom headers to outbound HTTP requests — like tracking IDs, authentication tokens, or metadata provided by libraries. But what happens when you want to add &lt;strong&gt;multiple&lt;/strong&gt; interceptors in a clean, reusable, and testable way?&lt;/p&gt;

&lt;p&gt;This blog post shows you how to chain multiple Feign &lt;code&gt;RequestInterceptor&lt;/code&gt; instances using a &lt;strong&gt;composite pattern&lt;/strong&gt;. You'll learn how to centralize header management, avoid duplication, and write integration tests to verify everything works as expected.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Define a Feign Client
&lt;/h2&gt;

&lt;p&gt;Let's start with a basic Feign client interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@FeignClient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fooClient"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"${foo.base-url}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;configuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FeignConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;FooClient&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/internal/foo"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;callInternalFoo&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;application.yml&lt;/code&gt;, we define the base URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;foo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;base-url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${FOO_BASE_URL:http://localhost:8080}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Important:&lt;/strong&gt; If you're calling your own application (localhost), be careful not to create a circular call like &lt;code&gt;/foo&lt;/code&gt; → Feign → &lt;code&gt;/internal/foo&lt;/code&gt; → Feign → ... This can cause a stack overflow or exhaust your thread pool. Ideally, use a mock server or a different port/environment for internal calls.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 2: The Magic — Composite Interceptor
&lt;/h2&gt;

&lt;p&gt;Here's the core idea: one interceptor that delegates to multiple others.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CompositeRequestInterceptor&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RequestInterceptor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RequestInterceptor&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;interceptors&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;CompositeRequestInterceptor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RequestInterceptor&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;interceptors&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;interceptors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;interceptors&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RequestTemplate&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RequestInterceptor&lt;/span&gt; &lt;span class="n"&gt;interceptor&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;interceptors&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;interceptor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Define Individual Interceptors
&lt;/h2&gt;

&lt;p&gt;You can create small, focused interceptors for each concern — even put them into separate modules/libraries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TrackingIdInterceptor&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RequestInterceptor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RequestTemplate&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;header&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-Tracking-ID"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;randomUUID&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthTokenInterceptor&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RequestInterceptor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RequestTemplate&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;header&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-Auth-Token"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"mockedTokenValue"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LibraryProvidedInterceptor&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RequestInterceptor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RequestTemplate&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;header&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-Library"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"libValue"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Configure the Feign Client
&lt;/h2&gt;

&lt;p&gt;Now we plug everything together in a configuration class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FeignConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;RequestInterceptor&lt;/span&gt; &lt;span class="nf"&gt;compositeInterceptor&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CompositeRequestInterceptor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AuthTokenInterceptor&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;TrackingIdInterceptor&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LibraryProvidedInterceptor&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 Pro tip: Avoid mixing &lt;code&gt;@Component&lt;/code&gt; and &lt;code&gt;@Bean&lt;/code&gt; registration for interceptors. Pick one method to avoid registering the same interceptor multiple times.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 5: Enable Feign Clients
&lt;/h2&gt;

&lt;p&gt;Make sure your application is configured to scan for Feign clients:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@EnableFeignClients&lt;/span&gt;
&lt;span class="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✅ Result — Interceptors Are Applied
&lt;/h2&gt;

&lt;p&gt;When your application makes a call via the &lt;code&gt;FooClient&lt;/code&gt;, all configured interceptors will be applied and headers added to the request. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X-Auth-Token: [mockedTokenValue]
X-Library: [libValue]
X-Tracking-ID: [4dfd7515-b73b-4a09-bc52-0d4de77d850f]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧪 Bonus: Verifying Headers with WireMock
&lt;/h2&gt;

&lt;p&gt;You can easily write an integration test using WireMock to verify that all headers are correctly sent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getRequestedFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urlEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/internal/foo"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-Auth-Token"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;equalTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mockedTokenValue"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-Library"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;equalTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"libValue"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-Tracking-ID"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;matchingUuid&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that all interceptors are executed as expected.&lt;/p&gt;




&lt;h2&gt;
  
  
  🙌 Wrap-up
&lt;/h2&gt;

&lt;p&gt;This pattern makes your Feign interceptors more modular, testable, and maintainable. You can add/remove behavior without rewriting configuration logic, and avoid the trap of overcomplicated header management.&lt;/p&gt;

&lt;p&gt;Thanks for reading — and if this helped you, feel free to ⭐ the &lt;a href="https://github.com/tarcalia/multiple-inteceptors" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; or share the article!&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>springboot</category>
      <category>feign</category>
      <category>java</category>
      <category>requestinterceptor</category>
    </item>
    <item>
      <title>The IntelliJ Settings I Always Change (Every. Single. Time.)</title>
      <dc:creator>Adam Tarcali</dc:creator>
      <pubDate>Tue, 10 Jun 2025 21:43:11 +0000</pubDate>
      <link>https://dev.to/tarcalia/the-intellij-settings-i-always-change-every-single-time-2oii</link>
      <guid>https://dev.to/tarcalia/the-intellij-settings-i-always-change-every-single-time-2oii</guid>
      <description>&lt;p&gt;Whenever I get a new machine, reinstall my system, or start at a new workplace with a freshly installed IntelliJ IDEA, there are a few key settings I always configure right away. They save time, reduce friction, and help me stay focused on writing code instead of fighting the IDE.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Auto Import on the Fly&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In the past, I used to lose precious minutes manually importing every missing package — especially when pasting code snippets from colleagues or external sources. Enabling “Auto-import on the fly” ensures that IntelliJ automatically takes care of import statements as I write code.&lt;br&gt;&lt;br&gt;
It might seem like a small thing, but over the course of a day (or sprint), it adds up to a lot of saved time and fewer frustrating interruptions.&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;Settings → Editor → General → Auto Import →Optimize imports on the fly&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;Settings → Editor → General → Auto Import →Add unambiguous imports on the fly&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  2. &lt;strong&gt;Optimize ‘Class Count to Use Import with '*'’&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There’s a long-standing debate: should you import individual classes or use wildcard imports when there are too many from the same package? Some teams even enforce thresholds like "only use wildcard if you import more than 5 classes."&lt;br&gt;&lt;br&gt;
To avoid inconsistencies and potential issues during code reviews or merges, I usually set this threshold to a very high number — effectively disabling wildcard imports.&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;Settings → Editor → Code Style → Java → Imports → Class count to use import with *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;Settings → Editor → Code Style → Java → Imports → Names count to use static import with *&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  3. &lt;strong&gt;Compact Mode (Flattened Tree View)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I learned to code on a tiny-screen laptop. With limited screen real estate, navigating long folder trees was a pain.&lt;br&gt;&lt;br&gt;
Enabling &lt;strong&gt;Compact Mode&lt;/strong&gt; (in the Project tool window) tightens up the spacing, making the file tree more readable — especially on smaller screens — without sacrificing clarity.&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;Settings → Appearance → UI Options →Compact Mode&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  4. &lt;strong&gt;Show Editor Tabs Vertically (on the side)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you’re like me and tend to keep multiple files open (especially during deep work), you’ve probably seen this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;FooService&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;FooServiceRepository&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;FooServiceController&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All squeezed into horizontal tabs like this:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;code&gt;FooServ... | FooServ... | FooServ...&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not great. To solve this, I move the editor tabs to the &lt;strong&gt;side&lt;/strong&gt;. That way, I get to see the full class names, can adjust their width, and enjoy slightly more vertical space in the actual code editor.&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;Settings → Editor → General → Editor Tabs → Tab placement → Right&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  5. &lt;strong&gt;Keep Package Hierarchy Intact (Yes, Really)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I know a lot of folks love “Flatten Packages” for a cleaner, one-line view of their package structure.&lt;br&gt;&lt;br&gt;
But personally, I prefer keeping the full hierarchy visible. It helps me better understand the module and package architecture — especially in larger codebases where structure &lt;strong&gt;matters&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Also, I find it more intuitive when navigating between similarly named classes across packages.&lt;br&gt;&lt;br&gt;
To each their own, but if you’re like me, make sure to &lt;strong&gt;disable Flatten Packages&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;Project View → Options → Appearance → Uncheck “Flatten Packages”&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Do you have similar IntelliJ rituals? Or any settings you can’t live without?&lt;br&gt;&lt;br&gt;
Let me know in the comments — I’d love to pick up a few new tips too. 😊&lt;/p&gt;

</description>
      <category>intellij</category>
      <category>productivity</category>
      <category>java</category>
      <category>programming</category>
    </item>
    <item>
      <title>Developer Tools – Is This IntelliJ Plugin a Must-Have?</title>
      <dc:creator>Adam Tarcali</dc:creator>
      <pubDate>Sun, 08 Jun 2025 18:05:45 +0000</pubDate>
      <link>https://dev.to/tarcalia/developer-tools-is-this-intellij-plugin-a-must-have-3o1j</link>
      <guid>https://dev.to/tarcalia/developer-tools-is-this-intellij-plugin-a-must-have-3o1j</guid>
      <description>&lt;p&gt;Chances are, every developer using IntelliJ has their own favorite plugins.&lt;br&gt;&lt;br&gt;
If I could only pick one – excluding the ones that come preinstalled – it would definitely be the &lt;a href="https://plugins.jetbrains.com/plugin/21904-developer-tools" rel="noopener noreferrer"&gt;Developer Tools – IntelliJ IDEs Plugin&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why do I love it?
&lt;/h2&gt;

&lt;p&gt;Because it brings so many small, everyday tools right into the IDE – tools I often need, and previously had to Google or open a terminal for.&lt;br&gt;&lt;br&gt;
Having them one click away just saves time and keeps my flow intact.&lt;br&gt;&lt;br&gt;
Let me highlight a few that I personally find the most useful:&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ Handy Features I Use Constantly
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🕒 Cron Expression Builder
&lt;/h3&gt;

&lt;p&gt;Need to generate a cron string? You can build it visually in seconds – no need to memorize which field is minutes, hours, or day of the week.&lt;/p&gt;

&lt;h3&gt;
  
  
  📅 Date and Time Converter
&lt;/h3&gt;

&lt;p&gt;Whether I need a Unix timestamp or a formatted date, it's right there – fast and customizable.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 Hashing Tool
&lt;/h3&gt;

&lt;p&gt;Quickly generate MD5, SHA, or other hashes – great when you need to work with APIs, auth tokens, or just test inputs.&lt;/p&gt;

&lt;h3&gt;
  
  
  📄 Lorem Ipsum Generator
&lt;/h3&gt;

&lt;p&gt;Self-explanatory – need placeholder text for UI or emails? A few clicks, and you've got paragraphs of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  📝 Notes
&lt;/h3&gt;

&lt;p&gt;Probably the one I use the most. Drop any thought, reminder, or snippet here without polluting your codebase with &lt;code&gt;// TODO&lt;/code&gt; or &lt;code&gt;// FIXME&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
Clean, accessible, and incredibly useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔑 Password Generator
&lt;/h3&gt;

&lt;p&gt;Need a secure password while developing something? No need to open a browser tab.&lt;/p&gt;

&lt;h3&gt;
  
  
  📷 QR Code &amp;amp; Barcode Generator
&lt;/h3&gt;

&lt;p&gt;More useful than you'd think – especially for frontend developers working with mobile or packaging systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧹 SQL Formatter
&lt;/h3&gt;

&lt;p&gt;Have a messy SQL query? One click and it's neatly formatted – no more squinting at spaghetti.&lt;/p&gt;

&lt;h3&gt;
  
  
  🆔 UUID Generator
&lt;/h3&gt;

&lt;p&gt;Testing something that needs unique IDs? Boom, instant UUIDs, right inside your IDE.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎨 Color Picker
&lt;/h3&gt;

&lt;p&gt;Super handy for frontend devs or game developers (hello LibGDX!).&lt;br&gt;&lt;br&gt;
Need a hex code or RGBA for a UI element? Grab it in seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;So… is it a must-have? Technically, no – it won't write your code or make architectural decisions.&lt;br&gt;&lt;br&gt;
It's not an AI tool.&lt;br&gt;&lt;br&gt;
But in real-world, everyday development, it can save you &lt;strong&gt;precious minutes&lt;/strong&gt; and remove small but annoying distractions.&lt;/p&gt;

&lt;p&gt;And honestly, for something free, lightweight, and that integrates so naturally into the IntelliJ ecosystem – it's worth a try.&lt;/p&gt;




&lt;p&gt;🔧 Have you used this plugin? Or do you have a different favorite tool I should know about? Let me know in the comments!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>intellij</category>
      <category>java</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
