Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Autowired and static method

I have @Autowired service which has to be used from within a static method. I know this is wrong but I cannot change the current design as it would require a lot of work, so I need some simple hack for that. I can't change randomMethod() to be non-static and I need to use this autowired bean. Any clues how to do that?

@Service
public class Foo {
    public int doStuff() {
        return 1;
    }
}

public class Boo {
    @Autowired
    Foo foo;

    public static void randomMethod() {
         foo.doStuff();
    }
}
like image 531
Taks Avatar asked Oct 10 '22 14:10

Taks


People also ask

Can we use Autowired in static method?

What you can do is @Autowired a setter method and have it set a new static field. When the bean gets processed, Spring will inject a Foo implementation instance into the instance field foo . It will then also inject the same Foo instance into the setStaticFoo() argument list, which will be used to set the static field.

How Spring bean is used in static method?

You can create a class that will allow access to any Bean from a static context. Most other answers here only show how to access a single class statically. The Proxy in the code below was added in case someone calls the getBean() method before the ApplicationContext is autowired (as this would result in a nullpointer).

Can a spring component have static methods?

Yes, A spring bean may have static methods too.

Can spring bean be static?

If we want to use spring bean ref in static methods we need to use ApplicationContextAware interface and override setApplicationContext() and make context object as static.


2 Answers

You can do this by following one of the solutions:

Using constructor @Autowired

This approach will construct the bean requiring some beans as constructor parameters. Within the constructor code you set the static field with the value got as parameter for constructor execution. Sample:

@Component
public class Boo {

    private static Foo foo;

    @Autowired
    public Boo(Foo foo) {
        Boo.foo = foo;
    }

    public static void randomMethod() {
         foo.doStuff();
    }
}

Using @PostConstruct to hand value over to static field

The idea here is to hand over a bean to a static field after bean is configured by spring.

@Component
public class Boo {

    private static Foo foo;
    @Autowired
    private Foo tFoo;

    @PostConstruct
    public void init() {
        Boo.foo = tFoo;
    }

    public static void randomMethod() {
         foo.doStuff();
    }
}
like image 185
Francisco Spaeth Avatar answered Oct 13 '22 02:10

Francisco Spaeth


You have to workaround this via static application context accessor approach:

@Component
public class StaticContextAccessor {

    private static StaticContextAccessor instance;

    @Autowired
    private ApplicationContext applicationContext;

    @PostConstruct
    public void registerInstance() {
        instance = this;
    }

    public static <T> T getBean(Class<T> clazz) {
        return instance.applicationContext.getBean(clazz);
    }

}

Then you can access bean instances in a static manner.

public class Boo {

    public static void randomMethod() {
         StaticContextAccessor.getBean(Foo.class).doStuff();
    }

}
like image 51
Pavel Horal Avatar answered Oct 13 '22 04:10

Pavel Horal