3

I have a class that would otherwise be a very generic POJO but I would like to inject a dependency in it because I would like to avoid passing that dependency as a (constructor) parameter:

//no managed context annotation because it's a simple POJO
public class QueuedBatch {

    //however, I would like to inject the context managed bean below
    @Autowired
    AsyncActionQueue asyncActionQueue;

Currently, no exception is thrown at deploy time but asyncActionQueue is null at runtime so I get a NullPointer when I hit the POJO.

How can I annotate my POJO to add it to the Spring managed context so that I can inject dependencies into it? AsyncActionQueue is a singleton and I would rather not be passing it to QueuedBatch as a (constructor) parameter.

This post is similar, except that I want to add my POJO into the managed context.

Community
  • 1
  • 1
amphibient
  • 29,770
  • 54
  • 146
  • 240
  • Annotate it as a @Component; it's not under Spring's control as written. If you call new to create it, then Spring knows nothing about it either. – duffymo Sep 06 '16 at 15:45
  • are you saying annotate `QueuedBatch` as a `@Component` ? – amphibient Sep 06 '16 at 15:47
  • *Don't* avoid passing a constructor parameter. If it's a required dependency, don't hide it. – chrylis -cautiouslyoptimistic- Sep 06 '16 at 15:48
  • 2
    Normal objects that are not annotated for Spring use aren't managed by Spring. So Spring knows nothing about them and so you can't directly inject a bean into an unmanaged class. The use of [`@Component`](http://docs.spring.io/spring-framework/docs/2.5.x/api/org/springframework/stereotype/Component.html) will be useful here. – px06 Sep 06 '16 at 15:48
  • 2
    Yes I am. I would also advise you to rethink your "rather not be passing it ...as constructor parameter". – duffymo Sep 06 '16 at 15:49
  • when I annotated it as `@Component`, the autowired object was still null – amphibient Sep 06 '16 at 15:54
  • I agree with @duffymo here, there is no real reason why you should avoid passing an `Object` as a parameter in the constructor to a class that Spring doesn't care about. – px06 Sep 06 '16 at 15:55
  • In the interest of full disclosure, using `new` in an `@Bean` will autowire fields. Field injection is still a Bad Thing. – chrylis -cautiouslyoptimistic- Sep 06 '16 at 16:03
  • as per the suggestions, I injected the dependency via the constructor and kept my POJO outside the Spring managed context – amphibient Sep 06 '16 at 16:09
  • 1
    Either all the pieces are under Spring's control or none of them are. You can't ask Spring to inject into POJO beans that you create by calling new. – duffymo Sep 06 '16 at 16:28
  • Better pass it using constructor rather than @Autowired. I feel POJO should not have any logic other than setters and getters, but its upto the developers only :) – Azim Sep 06 '16 at 19:10
  • autowiring in a non-spring managed class isn't allowed. it is only spring managed classes – Hary Aug 04 '23 at 17:19

1 Answers1

2

As the comments suggested you have 2 ways of dealing with this

  1. Pass the AsyncActionQueue as a parameter in the constructor of QueuedBatch. This doesnt require Spring to know anything about QueuedBatch, but enforces the dependency to be provided when an instance of QueuedBatch is created.

  2. Annotate the QueuedBatch class with @Component. And ensure that the package which contains QueuedBatch is included in the component scan when initializing the spring context. In this way, it becomes a spring managed bean allowing AsyncActionQueue to be autowired into it. You may change the scope of QueuedBatch component based on your requirement.

ameenhere
  • 2,203
  • 21
  • 36