10 Essential Spring Boot Utility Classes to Cut Your Code in Half
This article showcases ten built‑in Spring Boot utilities—including version retrieval, system property access, temporary and home directory handling, method introspection, generic type resolution, process ID extraction, property binding, and package path registration—each illustrated with concise code examples that dramatically reduce the need for custom helper classes.
Environment: Spring Boot 3.5.0
Spring & Boot version information
SpringVersion.getVersion(); // reads version from JAR metadata
SpringBootVersion.getVersion(); // returns "3.5.0" (hard‑coded in source)Accessing system properties
Utility class SystemProperties provides a static get method that checks a system property first and falls back to the corresponding environment variable.
public static String get(String... properties) {
for (String property : properties) {
try {
String override = System.getProperty(property);
override = (override != null) ? override : System.getenv(property);
if (override != null) {
return override;
}
} catch (Exception ignored) {}
}
return null;
}Temporary directory
ApplicationTempgives access to a per‑application temporary directory that remains the same across restarts.
@Component
public class UtilRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.err.println(new ApplicationTemp().getDir());
System.err.println(new ApplicationTemp(ExcelExportMain.class).getDir());
}
}Sample output:
C:\xxx\Local\Temp\6CE6073CFBB362554F12857D5719C56C45591EED
C:\xxx\Local\Temp\751B29068A945FC52288380FF45197427579C0CFApplication home directory
ApplicationHomelocates the main directory of a running application, handling JAR files, exploded archives, and plain classpath runs.
@Component
public class HomeRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.err.println(new ApplicationHome().getDir());
System.err.println(new ApplicationHome(ExcelExportMain.class).getDir());
}
}Typical output when running from a JAR:
D:\xxx\spring-boot-comprehensive
D:\xxx\spring-boot-comprehensive\target\classesMethod discovery
MethodIntrospector.selectMethodscan locate all methods annotated with a specific annotation, traversing interfaces, super‑classes, and handling generic signatures.
Set<Method> methods = MethodIntrospector.selectMethods(
UserService.class,
new ReflectionUtils.MethodFilter() {
@Override
public boolean matches(Method method) {
return method.isAnnotationPresent(Pack.class);
}
}
);Method parameter utilities
MethodParameterencapsulates a Method or Constructor together with a parameter index, allowing retrieval of parameter annotations and generic types.
Method method = UserService.class.getDeclaredMethod("create", String.class, Integer.class);
MethodParameter param = new MethodParameter(method, 0);
Pack annotation = param.getParameterAnnotation(Pack.class);
System.err.println(annotation);
Method method2 = UserService.class.getDeclaredMethod("create", List.class);
MethodParameter param2 = new MethodParameter(method2, 0);
ParameterizedType type = (ParameterizedType) param2.getGenericParameterType();
System.err.println(type.getActualTypeArguments()[0]);Running result:
@com.pack.inner.Pack()
class com.pack.inner.UserGeneric type resolution
GenericTypeResolverresolves actual generic arguments of classes, interfaces, or super‑classes, overcoming type erasure.
public class GenericTypeResolverTest {
public interface BaseDao<T, ID> {}
public abstract class AbstractService<T> {}
public class UserDao implements BaseDao<User, Long> {}
public class UserService extends AbstractService<User> {}
public static void main(String[] args) {
Class<?> entityCls = GenericTypeResolver.resolveTypeArgument(UserService.class, AbstractService.class);
System.out.println("UserDao generic entity type: " + entityCls.getSimpleName()); // User
Class<?>[] allTypes = GenericTypeResolver.resolveTypeArguments(UserDao.class, BaseDao.class);
System.out.println("Primary key type: " + allTypes[1].getSimpleName()); // Long
}
}Running result:
UserDao generic entity type: User
Primary key type: LongProcess ID
ApplicationPidreturns the current JVM PID (e.g., "26052"). Registering ApplicationPidFileWriter via META-INF/spring.factories writes the PID to application.pid on startup.
// META-INF/spring.factories
org.springframework.context.ApplicationListener=\
org.springframework.boot.context.ApplicationPidFileWriterProperty binding
Use @ConfigurationProperties to bind a group of configuration entries to a POJO.
@Component
@ConfigurationProperties(prefix = "pack.app")
public class NameProperties {
private String title;
private String version;
private List<String> author;
}
# application.yml
pack:
app:
title: xxxooo
version: 1.0.0
author: pack,xg,wcyIf a property name differs from the field name, @Name can rename it; @Delimiter changes the list separator.
@Name("v")
private String version;
@Delimiter("@")
private List<String> author;
# yaml example
pack:
app:
v: 1.0.0
author: pack@xg@wcyPackage path retrieval and registration
AutoConfigurationPackages.get(context)returns the base packages detected by Spring Boot. Custom packages can be registered with AutoConfigurationPackages.register, which is useful for third‑party auto‑configuration components.
@Component
public class PackagePathRunner implements CommandLineRunner {
private final ApplicationContext context;
public PackagePathRunner(ApplicationContext context) { this.context = context; }
@Override
public void run(String... args) throws Exception {
System.err.println(AutoConfigurationPackages.get(context));
}
}
public class PkgBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
AutoConfigurationPackages.register(registry, "cn.pack", "org.pack");
}
}Note: registering packages does not trigger component scanning for those packages; it merely makes the package list available to other auto‑configuration mechanisms.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
