Why Static Field Injection Fails in Spring 6 and How to Do It Correctly

This article examines why Spring 6 does not support injecting static fields or methods with @Resource, @Autowired, or @Inject, demonstrates the resulting errors, and presents proper ways to inject static dependencies using instance‑method or constructor injection, backed by source‑code analysis of the relevant bean post‑processors.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Why Static Field Injection Fails in Spring 6 and How to Do It Correctly

1. Static Field & Method Injection

First we verify that Spring does not allow injection into static fields or methods.

1.1 @Resource injection

@Component
public class PersonController {
  @Resource
  private static PersonService ps;
}

When the container starts, an error is logged indicating that @Resource does not support static field injection.

1.2 @Autowired injection

@Component
public class PersonController {
  @Autowired
  private static PersonService ps ;
  public String toString() {
    return "PersonController [ps=" + ps + "]";
  }
}

Running the application prints:

PersonController [ps=null]

Although @Autowired does not inject the static field, it does not throw an exception; the silent failure can later cause a NullPointerException.

1.3 @Resource method injection

private static PersonService ps ;
@Resource
public static void setPs(PersonService personService) {
  ps = personService ;
}

Container startup again throws a clear error that static method injection is not supported.

1.4 @Autowired method injection

// Same as above, replace @Resource with @Autowired

Output includes a log message stating that static field injection is not supported, and the bean prints PersonController [ps=null] without throwing an exception.

1.5 @Inject injection

First add the Jakarta Inject dependency:

<dependency>
  <groupId>jakarta.inject</groupId>
  <artifactId>jakarta.inject-api</artifactId>
  <version>${version}</version>
</dependency>

Usage is identical to @Resource/@Autowired:

@Inject
private static PersonService ps ;

Running the program produces the same log as @Autowired and the same null output.

All the above experiments confirm that static fields or methods cannot be injected by any of these annotations.

2. Correctly Injecting a Static Field

2.1 Instance‑method injection

public class PersonController {
  private static PersonService ps;
  @Resource
  public void setPs(PersonService personService) {
    ps = personService ;
  }
}

All three annotations (@Resource, @Autowired, @Inject) work when applied to a non‑static setter method.

2.2 Constructor injection

private static PersonService ps;
public PersonController(PersonService personService) {
  ps = personService ;
}

Constructor injection does not require any annotation and correctly assigns the static reference.

3. Source Code Analysis

The handling of @Resource is performed by CommonAnnotationBeanPostProcessor , while @Autowired and @Inject are processed by AutowiredAnnotationBeanPostProcessor .

3.1 @Resource processing

During bean definition merging, the processor scans for fields and methods annotated with @Resource. If a static field or method is found, it throws an IllegalStateException indicating that static injection is not supported.

public class CommonAnnotationBeanPostProcessor {
  public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
  }
}

private InjectionMetadata findResourceMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
  InjectionMetadata metadata = buildResourceMetadata(clazz);
  return metadata;
}

private InjectionMetadata buildResourceMetadata(Class<?> clazz) {
  // field check
  ReflectionUtils.doWithLocalFields(targetClass, field -> {
    if (Modifier.isStatic(field.getModifiers())) {
      throw new IllegalStateException("@Resource annotation is not supported on static fields");
    }
  });
  // method check
  ReflectionUtils.doWithLocalMethods(targetClass, method -> {
    if (Modifier.isStatic(method.getModifiers())) {
      throw new IllegalStateException("@Resource annotation is not supported on static methods");
    }
  });
}

This check occurs before the actual injection phase.

3.2 @Autowired processing

@Autowired and @Inject share the same processor. It also scans fields and methods, logs a warning for static members, and skips injection.

public class AutowiredAnnotationBeanPostProcessor {
  public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    findInjectionMetadata(beanName, beanType, beanDefinition);
  }

  private InjectionMetadata findInjectionMetadata(String beanName, Class<?> beanType, RootBeanDefinition beanDefinition) {
    InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
    return metadata;
  }

  private void buildAutowiringMetadata(Class<?> clazz) {
    ReflectionUtils.doWithLocalFields(targetClass, field -> {
      if (Modifier.isStatic(field.getModifiers())) {
        logger.info("Autowired annotation is not supported on static fields: " + field);
        return;
      }
    });
    ReflectionUtils.doWithLocalMethods(targetClass, method -> {
      if (Modifier.isStatic(method.getModifiers())) {
        logger.info("Autowired annotation is not supported on static methods: " + method);
        return;
      }
    });
  }
}

The actual injection happens later in AbstractAutowireCapableBeanFactory#populateBean.

In summary, static field or method injection is not supported by Spring's standard annotations; the proper approaches are instance‑method or constructor injection.

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.

Backend Developmentdependency-injectionStatic Fields
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.