需求:elasticsearch中,每天的数据放在当天的索引中,如2022.08.23。现有一个服务,定时从es中将数据拉取到mysql数据库中存储。

更新:可以通过SPEL进行动态注入

//es实体
@Document(indexName = "#{ T(com.xxx包名.xxx.xxx类名).xxx方法() }")

=========================================================================

考虑的点:java中es映射实体需要@Document注解指定连接的elasticsearch索引,需要动态修改@Document中indexName字段来指定索引。可以通过注入bean的方式实现,通过以下代码来获取索引名。

//es实体
@Document(indexName = "#{@esIndex}")
//通过配置类,注入bean

@Configuration
public class EsIndexConfig {


    /**
     * es 索引
     * @return
     */
    @Bean(name = "esIndex")
    public static String index(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
        String date = sdf.format(new Date());
        System.out.println(date);
        return "prod_" + date;
    }
}

问题:bean默认只有在服务启动时加载一次,即服务一旦启动,第二天从这个bean中取的仍然是昨天启动时的内容。现需要在第二天时,我们从bean中获取的是当天的时间,如何实现?

实现:通过bean的销毁与重载实现。

    @Scheduled(cron = "0 0/1 * * * ?")
    public void pullNetLog(){
        /**
         * 由于索引每天都会改变,可以通过注入bean的方式在es映射实体的@document中获取索引
         * 但是bean默认只有在服务启动时加载
         * 若需动态改变bean,设置定时任务,销毁这个bean之后再重新加载
         */
        //获取上下文
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        //销毁指定实例 esIndex是bean实例名称 name="esIndex"
        defaultListableBeanFactory.destroySingleton("esIndex");
        //按照旧有的逻辑重新获取实例,EsIndexConfig是我自己逻辑中的类
        String index = EsIndexConfig.index();
        //重新注册同名实例,这样在其他地方注入的实例还是同一个名称,但是实例内容已经重新加载
        defaultListableBeanFactory.registerSingleton("esIndex",index);

springboot定时任务,销毁bean后再重新加载

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐