1、问题:
在线程runnable中,无法将需要的kafkaTemplate(或者其他类)注入
2、解决方案:
通过封装ApplicationContex类(继承ApplicationContextAware),获取kafkaTemplate的bean实例。
3、代码演示:
SpringContextUtil.java工具类
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.util.Locale;
/**
* @author yanghao
* @Description:
* @date 2018/12/21 16:57
*/
//spring 中通过ApplicationContext getBean获取注入对象, 必须在需要注入之前(被依赖)
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
*/
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
SpringContextUtil.applicationContext = context;
}
/**
* 取得存储在静态变量中的ApplicationContext.
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
* 这里重写了bean方法,起主要作用
* @param beanName
* @return Object 一个以所给名字注册的bean的实例
* @throws BeansException
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
public static Object getBean(String beanName) throws BeansException{
return applicationContext.getBean(beanName);
}
public static Object getMessage(String key) {
return applicationContext.getMessage(key, null, Locale.getDefault());
}
/**
* 清除applicationContext静态变量.
*/
public static void cleanApplicationContext() {
applicationContext = null;
}
private static void checkApplicationContext() {
if (applicationContext == null) {
throw new IllegalStateException("applicaitonContext未注入");
}
}
}
线程注入:
import com.chargedot.server.producerdemo.service.PrintService;
import com.chargedot.server.producerdemo.utils.SpringContextUtil;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
/**
* @author yanghao
* @Description:
* @date 2018/12/21 17:22
*/
public class Event implements Runnable{
KafkaTemplate kafkaTemplate = (KafkaTemplate) SpringContextUtil.getBean("kafkaTemplate");
// PrintService printService = (PrintService) SpringContextUtil.getBean("printService"); //获取bean实例
@Override
public void run() {
kafkaTemplate.send(消息);
}
}
启动类:
import com.chargedot.platformservice.util.SpringContextUtil;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
@EnableCircuitBreaker
@EnableEurekaClient
public class CommunicateAdapterServiceApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(CommunicateAdapterServiceApplication.class, args);
new SpringContextUtil().setApplicationContext(context); //获取bean
}
}
如果你也有和我一样的问题,不妨试试这个。