Unlock Spring’s Hidden Power: Essential Utility Classes for Faster Backend Development

This article explores Spring 5.3.23’s core utility classes—including ID generators, concurrent LRU cache, concurrency throttling, StopWatch timing, digest calculation, method invocation, reflection helpers, route matching, collection utilities, and placeholder parsing—providing code examples, usage guidelines, and best practices to boost backend development efficiency.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Unlock Spring’s Hidden Power: Essential Utility Classes for Faster Backend Development

1. Introduction

Spring framework offers many powerful utility classes that help developers work more efficiently. This article delves into the features, usage, and best practices of Spring’s core utilities.

2. Spring Core Utility Classes

2.1 Unique ID Generators

Spring provides three default ID generators and an extensible IdGenerator interface.

@FunctionalInterface
public interface IdGenerator {
  UUID generateId();
}

Examples:

SimpleIdGenerator idG = new SimpleIdGenerator();
for (int i = 0; i < 3; i++) {
  System.out.println(idG.generateId());
}

Output:

00000000-0000-0000-0000-000000000001
00000000-0000-0000-0000-000000000002
00000000-0000-0000-0000-000000000003

JdkIdGenerator uses UUID.randomUUID():

JdkIdGenerator idG = new JdkIdGenerator();
for (int i = 0; i < 3; i++) {
  System.out.println(idG.generateId());
}
c63482d8-7a87-465a-a421-ef52d1fedf42
8eafc317-d994-4a1f-884a-dc4911a6e12b
f969bef3-1d2b-448e-9272-8810db002fb9

AlternativeJdkIdGenerator uses SecureRandom for better security and performance.

AlternativeJdkIdGenerator idG = new AlternativeJdkIdGenerator();
for (int i = 0; i < 3; i++) {
  System.out.println(idG.generateId());
}

2.2 Concurrent Local Cache (LRU)

A simple LRU cache backed by ConcurrentHashMap and ConcurrentLinkedDeque.

// Cache with capacity 2, value generated when missing
ConcurrentLruCache<String, String> cache = new ConcurrentLruCache<>(2, key -> {
  return String.format("%s-%d", key, new Random().nextInt(1000000));
});
cache.get("a");
System.out.println(cache.get("a"));
System.out.println("------------");
System.out.println(cache.get("b"));
System.out.println("------------");
System.out.println(cache.get("a"));
System.out.println("------------");
System.out.println(cache.get("c"));
System.out.println("------------");
System.out.println(cache.get("b"));

Output example:

a-988467
------------
b-604481
------------
a-988467
------------
c-435476
------------
b-491324

2.3 Concurrency Throttle

Abstract class to limit concurrent access, with a default AOP‑based interceptor.

public abstract class ConcurrencyThrottleSupport implements Serializable {
  public static final int UNBOUNDED_CONCURRENCY = -1;
  public static final int NO_CONCURRENCY = 0;
  private transient Object monitor = new Object();
  private int concurrencyLimit = UNBOUNDED_CONCURRENCY;
  private int concurrencyCount = 0;
  protected void beforeAccess() { /* TODO */ }
  protected void afterAccess() { /* TODO */ }
}
public class ConcurrencyThrottleInterceptor extends ConcurrencyThrottleSupport implements MethodInterceptor, Serializable {
  public ConcurrencyThrottleInterceptor() {
    setConcurrencyLimit(1);
  }
  @Override
  public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    beforeAccess();
    try {
      return methodInvocation.proceed();
    } finally {
      afterAccess();
    }
  }
}

Usage via a Spring advisor:

@Component
public class PackAdvisor extends DefaultPointcutAdvisor {
  public PackAdvisor() {
    super(new ConcurrencyThrottleInterceptor());
  }
}

2.4 StopWatch – Measuring Execution Time

static StopWatch watch = new StopWatch("task");
public static void entry() throws Exception {
  watch.start("task - 1");
  System.out.println("TODO - 1");
  TimeUnit.SECONDS.sleep(2);
  watch.stop();
  task2();
  task3();
}
public static void task2() throws Exception {
  watch.start("task - 2");
  System.out.println("TODO - 2");
  TimeUnit.SECONDS.sleep(1);
  watch.stop();
}
public static void task3() throws Exception {
  watch.start("task - 3");
  System.out.println("TODO - 3");
  TimeUnit.SECONDS.sleep(3);
  watch.stop();
}
public static void main(String[] args) throws Exception {
  entry();
  System.out.println(watch.prettyPrint());
}

Sample output shows total time and per‑task percentages.

2.5 DigestUtils – MD5 Hashing

Utility for MD5 digest without extra dependencies.

byte[] datas = "这是敏感数据".getBytes(StandardCharsets.UTF_8);
String ret = DigestUtils.md5DigestAsHex(datas);
System.out.println(ret);
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(datas);
System.out.println(HexUtils.toHexString(digest));

Both methods produce identical results.

MD5 output
MD5 output

2.6 MethodInvoker – Declarative Method Calls

static class PersonService {
  private void save(String name) {
    System.out.printf("save...%s%n", name);
  }
}
public static void main(String[] args) throws Exception {
  MethodInvoker invoker = new MethodInvoker();
  invoker.setTargetObject(new PersonService());
  invoker.setTargetMethod("save");
  invoker.setArguments("张三");
  invoker.prepare();
  invoker.invoke();
}

2.7 ReflectionUtils – Simplified Reflection

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
@interface Pack {}
static class PersonService {
  private int age;
  @Pack private String name;
  public void save(String name) { System.out.printf("save...%s%n", name); }
  @Pack public void query() { System.out.println("query..."); }
}
public static void main(String[] args) {
  List<Field> fields = new ArrayList<>();
  ReflectionUtils.doWithFields(PersonService.class, fields::add,
    field -> field.isAnnotationPresent(Pack.class));
  System.out.println(fields);
  List<Method> methods = new ArrayList<>();
  ReflectionUtils.doWithMethods(PersonService.class, methods::add,
    method -> method.isAnnotationPresent(Pack.class));
  System.out.println(methods);
}

2.8 RouteMatcher – Path Pattern Matching

String pattern = "/api-1/**";
PathPatternRouteMatcher routeMatcher = new PathPatternRouteMatcher();
Route route = routeMatcher.parseRoute("/api-1/users/666");
boolean ret = routeMatcher.match(pattern, route);
System.out.printf("ret = %b%n", ret);
route = routeMatcher.parseRoute("/api-2/demos");
ret = routeMatcher.match(pattern, route);
System.out.printf("ret = %b%n", ret);
RouteMatcher output
RouteMatcher output

2.9 CollectionUtils – Common Collection Operations

List<String> datas = new ArrayList<>();
boolean ret = CollectionUtils.isEmpty(datas);
System.out.printf("ret = %b%n", ret);
int[] nums = {1,2,3,4,5,6};
List<?> list = CollectionUtils.arrayToList(nums);
System.out.println(list);
List<String> source = new ArrayList<>();
source.add("a"); source.add("b"); source.add("c");
List<String> candidates = new ArrayList<>();
candidates.add("a"); candidates.add("e");
ret = CollectionUtils.containsAny(source, candidates);
System.out.printf("ret = %b%n", ret);

2.10 PropertyPlaceholderHelper – Placeholder Resolution

PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
Properties properties = new Properties();
properties.put("pack.name", "张三");
String value = helper.replacePlaceholders("${pack.name}", properties);
System.out.println(value);

Output: 张三

In summary, the article examined Spring’s core utility classes, which can significantly improve developer productivity.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaCacheconcurrencyspringID Generatorutilities
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.