Reputation: 15368
Let's say we have a class:
public class MyClass {
@Autowired private AnotherBean anotherBean;
}
Then we created an object of this class (or some other framework have created the instance of this class).
MyClass obj = new MyClass();
Is it possible to still inject the dependencies? Something like:
applicationContext.injectDependencies(obj);
(I think Google Guice has something like this)
Upvotes: 158
Views: 91363
Reputation: 251
Found the following way useful for my use case. Sharing here for reference, credit goes to the blogger entirely. This creates a static field and populates that from Spring and then provides a public static method which returns the field populated above.
https://sultanov.dev/blog/access-spring-beans-from-unmanaged-objects/
Upvotes: 0
Reputation: 1888
This worked for me:
@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
See more information: https://docs.spring.io/spring-javaconfig/docs/1.0.0.m3/reference/html/creating-bean-definitions.html
Upvotes: 0
Reputation: 1684
I used a different approach. I had spring loaded beans that I wanted to call from my extended classes of a third-party library that created its own threads.
I used approach I found here https://confluence.jaytaala.com/display/TKB/Super+simple+approach+to+accessing+Spring+beans+from+non-Spring+managed+classes+and+POJOs
In the non-managed class:
{
[...]
SomeBean bc = (SomeBean) SpringContext.getBean(SomeBean.class);
[...]
bc.someMethod(...)
}
And then as a helper class in the main application:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContext implements ApplicationContextAware
{
private static ApplicationContext context;
public static <T extends Object> T getBean(Class<T> beanClass)
{
return context.getBean(beanClass);
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException
{
SpringContext.context = context;
}
}
Upvotes: 6
Reputation: 7649
I wanted to share my solution that follows the @Configurable
approach as briefly
mentioned in @glaz666 answer because
Spring Neo4j & Aop starts
(which is irrelevant anyway)Spring Boot
is ready using @Configurable
approach (using ApplicationRunner
) I needed to follow the steps below in order to get it working
@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE, dependencyCheck = false)
to be placed on top of your Bean
that is to be manually instantiated. In my case the Bean
that is to be manually instantiated have @Autowired
services hence, the props to above annotation. XXXApplicaiton.java
(or the file that is annotated with @SpringBootApplication
) with the @EnableSpringConfigured
and @EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)
compile('org.springframework.boot:spring-boot-starter-aop')
and compile('org.springframework:spring-aspects:5.0.7.RELEASE')
Bean
that is annotated with @Configurable
anywhere and its dependencies should be autowired. *In regards to point #3 above, I am aware that the org.springframework.boot:spring-boot-starter-aop
transitively pulls the spring-aop
(as shown here mavencentral) but, in my case the Eclipse failed to resolve the @EnableSpringConfigured
annotations hence, why I explicitly added the spring-aop
dependency in addition to the starter. Should you face the same issue, just declare the dependency or go on adventure of figuring out
org.springframework.context.annotation.aspect.*
is not availableUpvotes: 4
Reputation: 3322
Just got the same need and in my case it was already the logic inside non Spring manageable java class which had access to ApplicationContext
. Inspired by scaffman.
Solved by:
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean(manuallyCreatedInstance);
Upvotes: 7
Reputation: 8721
You can also mark your MyClass with @Configurable annotation:
@Configurable
public class MyClass {
@Autowired private AnotherClass instance
}
Then at creation time it will automatically inject its dependencies. You also should have <context:spring-configured/>
in your application context xml.
Upvotes: 18
Reputation: 403441
You can do this using the autowireBean()
method of AutowireCapableBeanFactory
. You pass it an arbitrary object, and Spring will treat it like something it created itself, and will apply the various autowiring bits and pieces.
To get hold of the AutowireCapableBeanFactory
, just autowire that:
private @Autowired AutowireCapableBeanFactory beanFactory;
public void doStuff() {
MyBean obj = new MyBean();
beanFactory.autowireBean(obj);
// obj will now have its dependencies autowired.
}
Upvotes: 234