Spring 50例常见错误(十五)

文章整理来源:Spring编程常见错误50例_spring_spring编程_bean_AOP_SpringCloud_SpringWeb_测试_事务_Data-极客时间

案例37:混用 Redis 有不同序列化方式的 Template

         Redis 提供的两种 Template,一种 RedisTemplate,一种 stringRedisTemplate,用后者保存的数据,前者却获取不到

@SpringBootApplication
public class SpringdataApplication {

    SpringdataApplication(RedisTemplate redisTemplate,
            StringRedisTemplate stringRedisTemplate){
        String key = "mykey";
        stringRedisTemplate.opsForValue().set(key, "myvalue");

        Object valueGotFromStringRedisTemplate = stringRedisTemplate.opsForValue().get(key);
        System.out.println(valueGotFromStringRedisTemplate);

        Object valueGotFromRedisTemplate = redisTemplate.opsForValue().get(key);
        System.out.println(valueGotFromRedisTemplate);
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringdataApplication.class, args);
    }

}

         解析:RedisTemplate 默认使用的是 JDK 序列化,而  stringRedisTemplate 使用的是 StringRedisSerializer

        解决:统一指定  Serializer

案例 38:不适用的默认配置

        例如在一个依赖 Cassandra 的项目中,有时候在写入数据之后,并不能立马读到写入的数据

         解析:Cassandra 存在很多默认的配置,其中一项很重要的配置是 Consistency,在 driver 中默认为 LOCAL_ONE

basic.request {
 

  # The consistency level.
  #
  # Required: yes
  # Modifiable at runtime: yes, the new value will be used for requests issued after the change.
  # Overridable in a profile: yes
  consistency = LOCAL_ONE
 
//省略其他非关键配置 
}

          LOCAL_ONE 适合于独立部署的 Cassandra ,但大多数 Cassandra 有多数据中心多节点,比较合适的是用 LOCAL_QURAM

        解决:修改 Cassandra 的默认属性配置

@Override
protected SessionBuilderConfigurer getSessionBuilderConfigurer() {
    return cqlSessionBuilder -> {
        DefaultProgrammaticDriverConfigLoaderBuilder defaultProgrammaticDriverConfigLoaderBuilder = new DefaultProgrammaticDriverConfigLoaderBuilder();
        driverConfigLoaderBuilderCustomizer().customize(defaultProgrammaticDriverConfigLoaderBuilder);
        cqlSessionBuilder.withConfigLoader(defaultProgrammaticDriverConfigLoaderBuilder.build());
        return cqlSessionBuilder;
    };
}

@Bean
public DriverConfigLoaderBuilderCustomizer driverConfigLoaderBuilderCustomizer() {
    return loaderBuilder -> loaderBuilder
            .withString(REQUEST_CONSISTENCY, ConsistencyLevel.LOCAL_QUORUM.name())
}

 案例39:继承 Config 注入冗余的 Bean 

         Spring Data Cassandra 在连接 Cassandra 之后,会获取 Cassandra 的 Metadata 信息,这个内存占用量是比较大的,因为它存储了数据的 Token Range 等信息。如下图所示,有 4 个占用 40 多 M 连接

        解析:CassandraConfig 继承了 AbstractCassandraConfiguration ,在 AbstractCassandraConfiguration 已经定义了一个名为 cassandraSession 的 CqlSessionFactoryBean ,而 CassandraConfig 同样也定义了一个名为 session 的 CqlSessionFactoryBean ,从而导致容器中有两个  CqlSessionFactoryBean

@Configuration
@EnableCassandraRepositories
public class CassandraConfig extends AbstractCassandraConfiguration
     @Bean
     @Primary
     public CqlSessionFactoryBean session() {
         log.info("init session");
         CqlSessionFactoryBean cqlSessionFactoryBean = new CqlSessionFactoryBean();
         //省略其他非关键代码    
         return cqlSessionFactoryBean ;
     }
     //省略其他非关键代码
}
-----------------------------------------------

@Configuration
public abstract class AbstractSessionConfiguration implements BeanFactoryAware
    @Bean
    public CqlSessionFactoryBean cassandraSession() {
       CqlSessionFactoryBean bean = new CqlSessionFactoryBean();
       bean.setContactPoints(getContactPoints());
       //省略其他非关键代码
        return bean;
    }
    //省略其他非关键代码
}

        同时, 使用 Spring Data Cassandra 会创建两个 Session,systemSession 和 session ,它们都会获取 metadata。具体可参考代码 CqlSessionFactoryBean#afterPropertiesSet

@Override
public void afterPropertiesSet() {

   CqlSessionBuilder sessionBuilder = buildBuilder();
   // system session 的创建
   this.systemSession = buildSystemSession(sessionBuilder);

   initializeCluster(this.systemSession);
   // normal session 的创建
   this.session = buildSession(sessionBuilder);

   executeCql(getStartupScripts().stream(), this.session);
   performSchemaAction();

   this.systemSession.refreshSchema();
   this.session.refreshSchema();
}

         解决:修改 CassandraConfig 将 session() 改为 cassandraSession() ,覆盖掉父类创建 sessionBean

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值