项目增加spring-session模块所遇到的问题

2 篇文章 0 订阅
2 篇文章 0 订阅

使用session共享,原有项目加上spring-session开源模块
使用redis进行共享session的存储,redis服务端是sentinel集群

使用的spring版本

<properties>
<spring-version>3.1.2.RELEASE</spring-version>
</properties>

使用的spring- data -redis版本

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>

在xml文件中配置如下sample-session.xml


<?xml version="1.0" encoding="UTF-8"?><!-- spring session redis连接配置文件 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- jedis连接池参数 -->
<property name="maxTotal" value="300" /><!-- 设置最大连接数 -->
<property name="maxIdle" value="10" /><!-- 设置最多空闲连接 -->
<property name="testOnBorrow" value="true"/><!-- 启动检查是否存在 -->
<property name="maxWaitMillis" value="2000" /><!-- 设置最大阻塞时间,记住是毫秒数milliseconds -->
</bean>
<!-- 哨兵集群连接配置 start-->
<property name="master">
<bean class="org.springframework.data.redis.connection.RedisNode">
<property name="name" value="CAREERS_c42581_1"/>
</bean>
</property>
<property name="sentinels">
<set>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="10.27.18.225"/>
<constructor-arg name="port" value="26379"/>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="10.27.18.227"/>
<constructor-arg name="port" value="26379"/>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="10.27.18.228"/>
<constructor-arg name="port" value="26379"/>
</bean>
</set>
</property>
</bean>
<!-- 哨兵集群连接配置 end-->
<!-- redis连接池配置 -->
<constructor-arg index="0" ref="sentinelConfig"/>
<constructor-arg index="1" ref="jedisPoolConfig"/>
</bean>
<bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
<!-- 配置spring-session -->
<property name="maxInactiveIntervalInSeconds" value="6000"></property> <!-- 过期时间100分钟 -->
</bean>
</beans>

服务启动后报错


三月 05, 2018 3:20:40 下午 org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sentinelConfig' defined in class path resource [conf/spring/sample-session.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'sentinels' of bean class [org.springframework.data.redis.connection.RedisSentinelConfiguration]: Bean property 'sentinels' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1396)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118)
....
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'sentinels' of bean class [org.springframework.data.redis.connection.RedisSentinelConfiguration]: Bean property 'sentinels' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1064)
... 23 more

报错说明

无法把sentinels属性设置进sentinelConfig对象,因为sentinels属性是不可写的或没有一个有效的set方法。又或者set方法和get方法的参数类型是否一致?

在sentinelConfig对象(org.springframework.data.redis.connection.RedisSentinelConfiguration)中,
属性sentinels的set方法及get方法如下

public class RedisSentinelConfiguration {
… …
private Set<RedisNode> sentinels;
public void setSentinels(Iterable<RedisNode> sentinels) {
Assert.notNull(sentinels, "Cannot set sentinels to 'null'.");
this.sentinels.clear();
for (RedisNode sentinel : sentinels) {
addSentinel(sentinel);
}
}
public Set<RedisNode> getSentinels() {
return Collections.unmodifiableSet(sentinels);
}
… …
}

发现sentinels属性的set方法的参数类型与sentinels属性不一致
查看源码发现
Set extends Collection
Collection extends Iterable
属性sentinels类型虽然是Set,但是Iterable是其父类的父类,应该可以直接转换

解决方案

一, 升级spring版本,升级至spring-beans模块支持将Set类型属性调用其Iterable类型的set方法,实测当spring版本升级至3.2.5+时,可以排除错误。但是原有项目因为升级spring,引发了其它问题,如SpringMVC模块的406访问错误。
http://blog.csdn.net/linhenk/article/details/54611449
二, 继承RedisSentinelConfiguration类,重载其中sentinels的set方法

public class RpsRedisSentinelConfiguration extends RedisSentinelConfiguration {
… …
public void setSentinels(Set<RedisNode> sentinels) {
Assert.notNull(sentinels, "Cannot set sentinels to 'null'.");
this.sentinels.clear();
for (RedisNode sentinel : sentinels) {
addSentinel(sentinel);
}
}
… …
}

并修改sample-session.xml文件,修改spring容器初始化的具体实现类为自定义

<bean id="sentinelConfig"
class="org.springframework.data.redis.connection.RedisSentinelConfiguration"
class="com.***.***.RpsRedisSentinelConfiguration">
… …
</bean

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值