How to call a Spring @Service method before static initialization (before Spring context is fully loaded)?

2 weeks ago 13
ARTICLE AD BOX

I have a Spring application where I need to initialize a nodeId very early during application startup.

The problem is:

nodeId is used inside static blocks of some classes.

One of those classes is DeploymentConfig.

DeploymentConfig is loaded before Spring context is fully initialized.

Therefore, I cannot inject Spring beans normally.

Current Implementation

In ApplicationConfig I have:

public static String getNodeId() { if (nodeId == null) { setNodeId(); } return nodeId; } public static synchronized void setNodeId() { logger.info("Start setNodeId"); try { if (nodeId == null) { nodeId = NodeRegistryHolder.getNodeRegistry().getSerial().toString(); // nodeId = SpringContext.getBean(INodeRegistryService.class) // .getNodeRegistry().getName(); } } catch (Throwable e) { logger.error(e, e); } finally { logger.info("End setNodeId, nodeId = {}", nodeId); } }

This method must be executed at service startup because many static blocks depend on it.


The Service That Must Be Called

I need to call registerNode() from this Spring service:

@Service public class NodeRegistryServiceImpl implements INodeRegistryService { @CachePut("node-id") @Override public NodeRegistryDTO registerNode() throws BusinessException, DBException { String IP = GlobalUtil.getMachineIP(); ... NodeRegistry nodeRegistry = nodeRegistryRepository.registerNode(session, IP); ... return nodeRegistry.getDataTransferObject(); } }

Important context:

IP is dynamic (Kubernetes environment), so we must register the node at runtime.

We need a stable logical node identifier.

registerNode() must be called before any static blocks that use nodeId.


What I Tried

@DependsOn

ApplicationContextInitializer

Bean injection

BeanPostProcessor

Manual SpringContext.getBean(...)

But the problem is ordering:

Static blocks execute before Spring finishes context initialization, so beans are not ready and values become null.


The Core Problem

How can I:

Execute registerNode() very early during application startup

Make its result available to static blocks

Without breaking Spring lifecycle

In a large legacy project where removing static blocks is not feasible

Java version is 8 (cannot upgrade yet) and Tomcat is 8.5.


Question

What is the correct Spring-compatible way to:

Run logic before static blocks depend on it?

Or properly initialize static configuration that depends on Spring-managed beans?

Is there a clean architectural solution for this scenario?

Read Entire Article