Injecting beans into a class outside the Spring managed context

Solution 1:

You can do this:

ApplicationContext ctx = ...
YourClass someBeanNotCreatedBySpring = ...
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(
    someBeanNotCreatedBySpring,
    AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true);

You can use @Autowired and so on within YourClass to specify fields to be injected etc.

Solution 2:

One way to bring a bean into Spring despite its manufacture being external is to use a helper class marked as a @Configuration bean that has a method (marked with @Bean) that actually makes the instance and hands it back through Spring (which does its property injection and proxy generation at that point).

I'm not quite sure what scope you need; with prototype, you'll get a fresh bean in each place.

@Configuration
public class FooBarMaker {
    @Bean(autowire = Autowire.BY_TYPE)
    @Scope("prototype")
    public FooBar makeAFooBar() {
        // You probably need to do some more work in here, I imagine
        return new FooBar();
    }
}

You can inject properties required for manufacture into the @Configuration bean. (I use this to create instances of an interface where the name of the class to instantiate is defined at runtime.)

Solution 3:

suppose that u have the following dependency chain:

A --> B --> C --> x --> y -- > Z

A, B, C are spring managed beans (constructed and manged by spring framework) x, y are really simple POJOs that constructed by your application, without spring assistance

now if you want that y will get a reference to Z using spring that you need to have a 'handle' to the spring ApplicationContext

one way to do it is to implement ApplicationContextAware interface . In this case I would suggest that either A, B or C will implement this interface and will store the applicationContext reference in a static member.

so lets take Class C for example:

class C implmenets ApplicationContextAware{
    public static ApplicationContex ac;
     void setApplicationContext(ApplicationContext applicationContext)  {
               ac = applicationContext;
     }
 .............
}

now, in class y you should have:

(Z)(C.ac.getBean("classZ")).doSomething()

HTH -- Yonatan

Solution 4:

Another way to do this is to us use AspectJ. This is the recommended way of injection Spring beans into non-managed objects that are created with the new operator. See this for details:

http://www.javacodegeeks.com/2011/02/domain-driven-design-spring-aspectj.html