Spring @Autowired on a class new instance

João Menighin picture João Menighin · Sep 16, 2018 · Viewed 24.8k times · Source

I'm not so familiar with Spring and I have the following situation:

A repository class:

@Repository
public class MyRepository {
    // ...
}

A class that uses the repository class:

public class MyClass extends AbstractClass {

    @Autowired
    private MyRepository myRepository;

    //...
}

I know that if I annotate my MyClass with @Component and use it with an @Autowired, then the @Autowired MyRepository is resolved just fine. Problem is I am in a situation that I need to create new instances of MyClass with reflection. So MyRepository is never resolved and is null all the time.

Is there a way to use @Autowired in this situation?

Explaining better my situation: I have some implementations of AbstractClass. In a setup phase of my application I create a HashMap of these implementations. Basically:

{"MyClass", MyClass.class}
//...

Then I have a generic Controller that maps to the url /{class}?options=... Using the {class} @PathVariable, the HashMap above and reflection I am able to create a instance of a class based on the given options (this part is important). Do you guys think there's a better way of doing this?

Thanks in advance

Answer

Thomas Fritsch picture Thomas Fritsch · Sep 16, 2018

Spring itself offers some functionality for doing auto-wiring in your objects which you created by new or newInstance() or whatever.

To use it you need an AutowireCapableBeanFactory which you get by Spring's normal dependency injection with @Autowired.

@Autowired
private  AutowireCapableBeanFactory autowireCapableBeanFactory;

Then you use its autowireBean(Object) method to inject the @Autowired properties into your bean.

Object myBean = map.get(className).newInstance();
autowireCapableBeanFactory.autowireBean(myBean);

Design note:

Think well if you really need the approach above. The javadoc of AutowireCapableBeanFactory advises against using this interface for most use-cases:

This subinterface of BeanFactory is not meant to be used in normal application code: stick to BeanFactory or ListableBeanFactory for typical use cases.

Integration code for other frameworks can leverage this interface to wire and populate existing bean instances that Spring does not control the lifecycle of. This is particularly useful for WebWork Actions and Tapestry Page objects, for example.