Integrating Spring’s Inversion of Control (IoC) container with non-Spring-managed objects can be useful when you need to access Spring-managed beans within components or instances that are not managed by the Spring framework. Below are some common approaches to achieve this:
1. Using the ApplicationContext Directly
You can access Spring’s ApplicationContext (which holds the Spring container) and retrieve beans from it. The ApplicationContext instance can be injected into any Spring-managed bean or accessed statically.
Steps:
- Register the
ApplicationContextas a bean. - Use it to fetch beans manually.
Example:
package org.kodejava.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
context = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return context;
}
}
Retrieving the Bean:
From a non-Spring-managed class, you can access the Spring context like this:
package org.kodejava.spring;
import org.springframework.context.ApplicationContext;
public class NonSpringClass {
public void doSomething() {
ApplicationContext context = ApplicationContextProvider.getApplicationContext();
MyBean myBean = context.getBean(MyBean.class);
myBean.performTask();
}
}
2. Using @Configurable with AspectJ
Spring provides the @Configurable annotation, which can inject dependencies into objects not managed by Spring, such as those manually instantiated using the new operator. This requires AspectJ weaving to work.
Steps:
- Add
@Configurableto the class. - Enable annotation-driven dependency injection for AspectJ using Spring AOP.
Example:
package org.kodejava.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
@Configurable
public class NonSpringClass {
@Autowired
private MyBean myBean;
public void execute() {
myBean.performTask();
}
}
Configuration Example:
Add the following to your Spring configuration:
<context:spring-configured />
<tx:annotation-driven />
Ensure AspectJ weaving is enabled either at compile-time or runtime using a javaagent.
3. Using BeanFactory or AutowireCapableBeanFactory
Spring’s AutowireCapableBeanFactory can be used to autowire fields or methods in non-Spring-managed objects.
Example:
package org.kodejava.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class NonSpringClassFactory {
private final AutowireCapableBeanFactory beanFactory;
@Autowired
public NonSpringClassFactory(AutowireCapableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public NonSpringClass createNonSpringClass() {
NonSpringClass instance = new NonSpringClass();
beanFactory.autowireBean(instance);
return instance;
}
}
4. Programmatic Injection
If you cannot use annotations and static utility classes, you can always inject the Spring bean manually into the non-Spring-managed object.
Example:
package org.kodejava.spring;
import org.kodejava.spring.construct.MyBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public NonSpringClass nonSpringClass(MyBean myBean) {
return new NonSpringClass(myBean);
}
}
Non-Spring class:
package org.kodejava.spring;
public class NonSpringClass {
private final MyBean myBean;
public NonSpringClass(MyBean myBean) {
this.myBean = myBean;
}
public void execute() {
myBean.performTask();
}
}
5. Event Listeners and Publishers
If the interaction is event-driven, you can use Spring’s event-publishing infrastructure and handle events in non-Spring-managed objects.
Example:
The Spring-managed components publish events that can be consumed by non-Spring-managed listeners via custom hooks.
Recommendations:
- Choose
ApplicationContextorAutowireCapableBeanFactory: When dealing with legacy classes or objects where Spring cannot manage the lifecycle. - Use
@Configurable: When you need seamless dependency injection for dynamically created objects but can rely on AspectJ weaving.
