1.How to inject a spring bean into thread
2.How to start a thread inside spring bean.
here is my code.
MyThread.java
@Component
public class MyThread implements Runnable {
@Autowired
ApplicationContext applicationContext;
@Autowired
SessionFactory sessionFactory;
public void run() {
while (true) {
System.out.println("Inside run()");
try {
System.out.println("SessionFactory : " + sessionFactory);
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(10000);
System.out.println(Arrays.asList(applicationContext.getBeanDefinitionNames()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
i am calling run
method from below class like (Please suggest if i am following wrong appraoch for calling a thread inside spring bean )
@Component
public class MyServiceCreationListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext().getParent() == null) {
System.out.println("\nThread Started");
Thread t = new Thread(new MyThread());
t.start();
}
}
}
spring is not performing dependency injection on MyThread
class
In a Spring application, injecting one bean into another bean is very common. However, sometimes it's desirable to inject a bean into an ordinary object. For instance, we may want to obtain references to services from within an entity object. Fortunately, achieving that isn't as hard as it might look.
The problem is: spring container creates the singleton bean MySingletonBean only once, and thus only gets one opportunity to inject the dependencies into it. The container cannot provide MySingletonBean with a new instance of MyPrototypeBean every time one is needed.
When method student () is invoked by Spring to create its bean, it autowires the subject based on the type and satisfies its dependency. Let us verify it using the JUnit test.
To inject a bean into an unmanaged object, we must rely on the AnnotationBeanConfigurerAspect class provided in the spring-aspects.jar. Since this is a pre-compiled aspect, we would need to add the containing artifact to the plugin configuration.
There are a couple of things wrong with your setup.
Spring provides an abstraction to execute tasks, the TaskExecutor
. You should configure one and use that to execute your task not create a thread yourself.
Add this to your @Configuration
class.
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
return new ThreadPoolTaskExecutor();
}
Your MyThread
should be annotated with @Scope("prototype")
.
@Component
@Scope("prototype")
public class MyThread implements Runnable { ... }
Now you can inject these beans and an ApplicationContext
into your MyServiceCreationListener
@Component
public class MyServiceCreationListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private ApplicationContext ctx;
@Autowired
private TaskExecutor taskExecutor;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext().getParent() == null) {
System.out.println("\nThread Started");
taskExecutor.execute(ctx.getBean(MyThread.class));
}
}
}
This will give you a pre-configured, fresh instance of MyThread
and execute it on a Thread
selected by the TaskExecutor
at hand.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With