我正在为我的应用程序使用spring boot starter 2.2.0.RELEASE。我有一个卡夫卡消费者。现在,我想将我的spring实体注入到我的kafka使用者中(kafka使用者不由spring容器管理)。
我尝试了ApplicationContextAware,但并没有帮助我。我在kafka使用者中将applicationContext获取为null,因此无法从spring容器中获取bean。首次设置applicationContext时正确设置,但是第二次加载上下文时将其设置为null。 以下是我的应用程序的详细信息
@SpringBootApplication
@ComponentScan({"com.xyz.config_assign.service"})
public class ConfigAssignServer {
private static Logger log = LoggerFactory.getLogger(ConfigAssignServer.class);
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(ConfigAssignServer.class, args);
log.info("Started ConfigAssign Server!!! AppName= {} ", applicationContext.getApplicationName());
QkafkaClient.loadConfiguration();
}
}
我的所有应用程序类都存在于com.xyz.config_assign.service中,因此不会出现bean扫描问题。在添加Kafka用户之前,效果很好
我的ApplicationContextProvider正在使用著名的ApplicationContextAware
@Component
public class ApplicationContextProvider implements ApplicationContextAware{
public static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ApplicationContextProvider.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
现在是我的kafkaconsumer
public class ConfigAssignmentAssetTagChangeKafkaTopicProcessor implements BatchTopicProcessor<String, String> {
private Logger log = LoggerFactory.getLogger(ConfigAssignmentAssetTagChangeKafkaTopicProcessor.class);
private AssignConfigServiceImpl assignConfigServiceImpl;
public ConfigAssignmentAssetTagChangeKafkaTopicProcessor(){
ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
assignConfigServiceImpl = applicationContext.getBean(AssignConfigServiceImpl.class);
}
@Override
public void handleError(ConsumerRecords<String, String> arg0, Exception arg1) {
// TODO Auto-generated method stub
}
@Override
public void process(ConsumerRecords<String, String> records, long arg1) {}
}
我想为kafka消费者注入的服务是
@Service
public class AssignConfigServiceImpl implements AssignConfigService {
private Logger log = LoggerFactory.getLogger(AssignConfigServiceImpl.class);
@Autowired
private ConfigProfileDBService dbService;
public boolean assignConfigToAgents(List<UUID> agentList, long customerId) {
List<AgentConfigurationProfile> configProfiles =
dbService.getConfigurationProfilesForCustomer(customerId);
boolean isAssignSuccessful = assignConfigToAgents(agentList, customerId, configProfiles);
log.info("Config Assignment status ={}", isAssignSuccessful);
return isAssignSuccessful;
}
我使用的其他服务是
@Service
public class ConfigProfileDBService implements DBService {
private static Logger log = LoggerFactory.getLogger(ConfigProfileDBService.class);
@Autowired
private JdbcTemplate jdbcTemplate;
public List<AgentConfigurationProfile> getConfigurationProfilesForCustomer(Long customerId) {
List<AgentConfigurationProfile> agentConfigList;
}
}
有人可以让我知道出了什么问题。我尝试了多种在线解决方案,但没有为我工作。提前致谢。 注意:我尚未使用new运算符初始化任何类。
答案 0 :(得分:1)
基于问题和评论的澄清,并假设不可能将KafkaConsumer移交给Spring管理(这是我认为最好的解决方案):
@Autowired
在KafkaConsumer中不起作用,因此无需放置该注释。
我假设您在此行中的应用程序上下文为空:
ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
这意味着在创建Kafka Consumer时尚未调用ApplicationContextProvider#setApplicationContext
。除了注入,Spring还管理被管理对象的生命周期。由于您不是在春天,所以您是“自己的”,并且必须确保首先创建应用程序上下文,然后才创建其他对象(例如,像Kafka Consumer)。
当应用程序上下文启动时,它会在某个时刻一个接一个地添加bean,它还会到达ApplicationContextProvider
并调用其setter。
答案 1 :(得分:0)
我的主要问题是我的spring上下文被加载了两次。当我打印每个类的类加载器时,我发现我的应用程序正在运行两次。 (即,当我按F9后在intellij中进行调试时,我又重新回到了同一行,即
ConfigurableApplicationContext applicationContext = SpringApplication.run(ConfigAssignServer.class, args);
我的问题出在pom.xml中。我从pom中删除了以下依赖项,并且有效。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
请检查您的依赖性。希望它能帮助某人。享受编码:)