Pelicer
Pelicer

Reputation: 1584

Are Autowired fields accessible during class construction?

First, I'd like to address that this question does not relate to this post, which is about @Autowired fields being null due to the incorrect way to instanciate classes.

I have a few autowired fields in one of my classes. I also have another private field, header, that is used in most of my functions. So, to have a cleaner and more concise code, I wanted to fill header during class construction. The point is that, in order to fill header, I need to call functions that comes from an autowired instance.

This works fine:

public class Foo{

    @Autowired
    private SomeClass someInstance;

    private HttpHeaders headers;

    private void init(){
        String value = someInstance.getValue();
        headers = this.headers = new HttpHeaders();
        headers.set("key", value);
    }

    public void SomeFunction(){
        init(); //i don't want to call init()
        //header has it's key set to value, working fine
    }
}

But it doesn't seem right to me having the function init() to initialize headers. This is what constructors are for. So I want to do this:

public class Foo{

    @Autowired
    private SomeClass someInstance;

    private HttpHeaders headers;

    public Foo(){
        String value = someInstance.getValue(); //someInstance is null, I get NPE
        headers = this.headers = new HttpHeaders();
        headers.set("key", value);
    }

    public void SomeFunction(){
        //header is null, since the constructor threw an exception
    }
}

As commented on the code above, in that case someInstance is null. Are Autowired fields accessible during class construction? I don't how spring treats the autowiring and class creation, but makes sense to me that this should work.

Upvotes: 0

Views: 477

Answers (1)

csenga
csenga

Reputation: 4114

Note, @Autowired annotation is handled by AutowiredAnnotationBeanPostProcessor which populates the corresponding fields after the object was created.

The most obvious solution for your problem is to use constructor injection.

 public Foo(SomeClass someInstance){
..
}

If you want to go with the init method, you can rely on Spring to call your init method after the bean was created/populated, this can be achieved by placing the @PostConstruct annotation on your init method.

Upvotes: 3

Related Questions