-1

我正在为我的应用程序使用 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 运算符初始化任何类。

4

2 回答 2

1

基于对问题和评论的澄清,并假设不可能将 KafkaConsumer 移动到春季管理(我相信这是最好的解决方案):

@Autowired在 KafkaConsumer 中不起作用,因此无需添加该注释。

我假设您在这一行中的 Application 上下文为空:

 ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();

这意味着ApplicationContextProvider#setApplicationContext在您创建 Kafka Consumer 时尚未调用它。除了注入之外,Spring 还管理托管对象的生命周期。因为你不是在春天,所以你是“自己的”,你必须确保首先创建应用程序上下文,并且只有在创建其他对象之后才创建其他对象(例如 Kafka Consumer)。

当应用程序上下文启动时,它会在某个时间点一个接一个地添加 bean,在其他 bean 中,它也会到达ApplicationContextProvider并调用它的 setter。

于 2020-02-26T08:11:02.947 回答
0

我的主要问题是我的弹簧上下文被加载了两次。当我打印每个类的类加载器时,我发现我的应用程序运行了两次。(即,当我在按下 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>

请检查您的依赖项。希望它会帮助某人。享受编码:)

于 2020-02-27T18:41:07.747 回答