[英]Spring not injecting a bean into thread
1.How to inject a spring bean into thread 1.如何在线程中注入一个spring bean
2.How to start a thread inside spring bean. 2.如何在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 )我正在从下面的类调用
run
方法(请建议我是否遵循错误的方法来调用 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 spring 不在
MyThread
类上执行依赖注入
There are a couple of things wrong with your setup.您的设置有一些问题。
Spring provides an abstraction to execute tasks, the TaskExecutor
. Spring 提供了一个抽象来执行任务,即
TaskExecutor
。 You should configure one and use that to execute your task not create a thread yourself.您应该配置一个并使用它来执行您的任务,而不是自己创建线程。
Add this to your @Configuration
class.将此添加到您的
@Configuration
类。
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
return new ThreadPoolTaskExecutor();
}
Your MyThread
should be annotated with @Scope("prototype")
.你的
MyThread
应该用@Scope("prototype")
注释。
@Component
@Scope("prototype")
public class MyThread implements Runnable { ... }
Now you can inject these beans and an ApplicationContext
into your MyServiceCreationListener
现在你可以将这些 bean 和一个
ApplicationContext
注入你的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.这将为您提供一个预先配置的
MyThread
新实例,并在手头的TaskExecutor
选择的Thread
上执行它。
Your MyThread is created manually rather than via spring context new Thread(new MyThread());
你的 MyThread 是手动创建的,而不是通过 spring 上下文
new Thread(new MyThread());
so no chance for spring to inject a bean.所以春天没有机会注入豆子。
Instead you can add a trick with static access to spring context where you can get a necessary bean from the context (see here or here ).相反,您可以添加一个对 spring 上下文进行静态访问的技巧,您可以在其中从上下文中获取必要的 bean(请参阅此处或此处)。
Alternatively you can use ThreadLocal or InheritableThreadLocal to store necessary objects to be used in the thread.或者,您可以使用ThreadLocal或InheritableThreadLocal来存储要在线程中使用的必要对象。
You are creating Thread t = new Thread(new MyThread());
您正在创建
Thread t = new Thread(new MyThread());
.Spring container will not inject the dependency and also not maintain the life cycle of bean. .Spring 容器不会注入依赖,也不会维护 bean 的生命周期。
Example :示例:
@Component
@Scope("prototype")
public class PrintThread extends Thread{
@Override
public void run() {
System.out.println(getName() + " is running");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + " is running");
}
}
to access the thread object from spring context.从 spring 上下文访问线程对象。
public class ApplicationContextUtils implements ApplicationContextAware {
private static ApplicationContext ctx;
private static final String USER_THREAD = "printThread";
@Override
public void setApplicationContext(ApplicationContext appContext)
throws BeansException {
ctx = appContext;
}
public static ApplicationContext getApplicationContext() {
return ctx;
}
public static UserService getUserService(){return ctx.getBean(USER_THREAD );}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.