Can you use @Autowired with static fields?

JavaSpringAutowired

Java Problem Overview


Is there some way to use @Autowired with static fields. If not, are there some other ways to do this?

Java Solutions


Solution 1 - Java

In short, no. You cannot autowire or manually wire static fields in Spring. You'll have to write your own logic to do this.

Solution 2 - Java

@Component("NewClass")
public class NewClass{
    private static SomeThing someThing;

    @Autowired
    public void setSomeThing(SomeThing someThing){
        NewClass.someThing = someThing;
    }
}

Solution 3 - Java

@Autowired can be used with setters so you could have a setter modifying an static field.

Just one final suggestion... DON'T

Solution 4 - Java

Init your autowired component in @PostConstruct method

@Component
public class TestClass {
   private static AutowiredTypeComponent component;
   
   @Autowired
   private AutowiredTypeComponent autowiredComponent;

   @PostConstruct
   private void init() {
      component = this.autowiredComponent;
   }

   public static void testMethod() {
      component.callTestMethod();
   }
}

Solution 5 - Java

Create a bean which you can autowire which will initialize the static variable as a side effect.

Solution 6 - Java

Wanted to add to answers that auto wiring static field (or constant) will be ignored, but also won't create any error:

@Autowired
private static String staticField = "staticValue";

Solution 7 - Java

You can achieve this using XML notation and the MethodInvokingFactoryBean. For an example look here.

private static StaticBean staticBean;

public void setStaticBean(StaticBean staticBean) {
   StaticBean.staticBean = staticBean;
}

You should aim to use spring injection where possible as this is the recommended approach but this is not always possible as I'm sure you can imagine as not everything can be pulled from the spring container or you maybe dealing with legacy systems.

Note testing can also be more difficult with this approach.

Solution 8 - Java

You can use ApplicationContextAware

@Component
public class AppContext implements ApplicationContextAware{
    public static ApplicationContext applicationContext;

    public AppBeans(){
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

then

static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);

Solution 9 - Java

Disclaimer This is by no means standard and there could very well be a better spring way of doing this. None of the above answers address the issues of wiring a public static field.

I wanted to accomplish three things.

  1. Use spring to "Autowire" (Im using @Value)
  2. Expose a public static value
  3. Prevent modification

My object looks like this

private static String BRANCH = "testBranch";

@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
	BRANCH = branch;
}

public static String BRANCH() {
	return BRANCH;
}

We have checked off 1 & 2 already now how do we prevent calls to the setter, since we cannot hide it.

@Component
@Aspect
public class FinalAutowiredHelper {

@Before("finalMethods()")
public void beforeFinal(JoinPoint joinPoint) {
	throw new FinalAutowiredHelper().new ModifySudoFinalError("");
}

@Pointcut("execution(* com.free.content.client..*.finalSetBranch(..))")
public void finalMethods() {}


public class ModifySudoFinalError extends Error {
	private String msg;
	
	public ModifySudoFinalError(String msg) {
		this.msg = msg;
	}

	@Override
	public String getMessage() {
		return "Attempted modification of a final property: " + msg;
	}
}

This aspect will wrap all methods beginning with final and throw an error if they are called.

I dont think this is particularly useful, but if you are ocd and like to keep you peas and carrots separated this is one way to do it safely.

Important Spring does not call your aspects when it calls a function. Made this easier, to bad I worked out the logic before figuring that out.

Solution 10 - Java

Generally, setting static field by object instance is a bad practice.

to avoid optional issues you can add synchronized definition, and set it only if private static Logger logger;

@Autowired
public synchronized void setLogger(Logger logger)
{
    if (MyClass.logger == null)
    {
        MyClass.logger = logger;
    }
}

:

Solution 11 - Java

private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);

Solution 12 - Java

Solution 1 : Using Constructor @Autowired For Static Field

@Component
public class MyClass {

    private static MyService service;

    @Autowired
    public MyClass(MyService service) {
        TestClass.service= service;
    }
}

Solution 2 : Using @PostConstruct to set the value to Static Field

@Component
public class MyClass {

    private static MyService service;

    @Autowired
    private MyService srv;

    @PostConstruct
    public void init() {
        this.service= srv;
    }
}

Refer here for more detail

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser124722View Question on Stackoverflow
Solution 1 - JavaskaffmanView Answer on Stackoverflow
Solution 2 - JavaSedat BaşarView Answer on Stackoverflow
Solution 3 - Javavictor hugoView Answer on Stackoverflow
Solution 4 - Javaak-jView Answer on Stackoverflow
Solution 5 - JavaJhericoView Answer on Stackoverflow
Solution 6 - Javauser7294900View Answer on Stackoverflow
Solution 7 - JavaJARCView Answer on Stackoverflow
Solution 8 - JavaAliView Answer on Stackoverflow
Solution 9 - Javajozsef morrisseyView Answer on Stackoverflow
Solution 10 - JavaAdir DView Answer on Stackoverflow
Solution 11 - JavaAmol KakadeView Answer on Stackoverflow
Solution 12 - JavaNisarg PatilView Answer on Stackoverflow