Is Spring able to handle this user case? Neither property nor constructor injection


Is Spring able to handle this user case? Neither property nor constructor injection



Basically, I have a class A which depends on class B which in turn depends on a spring managed bean C, but I dont want to keep B as a class variable just use B inside one method for some reason. My solution is to create a static method get() in B which returns a instance of B. Now the problem is, C is not injected to B correctly.

// A cannot have B as a class/field variable.  public class A {     public void method(){         // B.get() returns a instance of B, but this instance is not the          // instance that spring created, it is the static "instance" in B.          B.get().doSomething();// ofcourse it throws out a nullpointer exception     } }  class B{     @Resource(name = "c")     private C c;      private static B instance;       public static B get() {          return instance==null ? (instance=new B()) : instance;     }      public void doSomething(){         c.toString();       // this line will break if c is not                             // injected to the instance of b      } }  @Service("c") class C {             } 

How do I solve this problem??




How do I instantiate an Object that uses generics with Spring framework?

1:



Simple autosave for Spring MVC form
The whole point of using Spring is it is a dependency injection framework, and you are hardcoding the dependency of B in A..
Putting Spring integration tests in different classes and packages
Try very hard not to do that.


Spring as a glorified factory; is this acceptable?
If you don't want to store B in an instance variable, pass it as an argument to the method..
Best way to check whether a certain exception type was the cause (of a cause, etc …) in a nested exception?
If you are stubborn about doing that then you have to get an ApplicationContext and load it yourself.


Searching for Generic Asynchronous Java Job Execution Framework / Library
An alternative might be to have B implement InitializingBean and then have your afterPropertiesSet method register the current instance with a static instance variable..
Client side object velocity


Spring Controller destroy method?

2:


There isn't a direct bit of spring to support this, but are are a couple of work arounds to solve the problem..
  1. grab hold of the ApplicationContext in B.get() and call getBean in order to get spring to construct B.

    Getting hold of the ApplicationContext is another mission as it is typically not held anywhere statically, have a look in the spring reference manual for 'dirty singleton'.
  2. Let spring construct the bean and then keep a reference to it in the instance variable:.
@Service('b') class B{ @Resource(name = "c") private C c;.
private static B instance;  public B(){     // sets the static here     // not ideal...should use afterProperties set or what ever the Annotation equivalent is     instance = this; }  public static B get() {      if( instance == null ){           throw new IllegalStateException("errr...say something useful here")      }      return instance; }  public void doSomething(){     c.toString();       // this line will break if c is not                         // injected to the instance of b  } 
}. I've seen 2.

used a couple of times on various projects, it's not pretty and if you have a choice don't do it, just get spring to wire the whole app.

But if you don't have a choice, it might be the least worst option..


3:


You'll have to get the bean programmatically from the Spring ApplicationContext, either within A#method(), or in the constructor of A or its initialization method, and caching the Spring injected B instance..



82 out of 100 based on 52 user ratings 202 reviews