我正在尝试使用Jedis使用Spring数据Redis将消息发布到通道.这是一个非常简单的Java配置:
@Bean(name="jedisConnectionFactory")
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(redisHostName);
factory.setPort(redisPort);
factory.setUsePool(true);
return factory;
}
@Bean(name="redisTemplate")
RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
return redisTemplate;
}
Run Code Online (Sandbox Code Playgroud)
其中redisPort = 6379,redisHostName ="localhost".
当我运行以下测试时:
@Test
public void testRedis(){
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
RedisTemplate<Object,Object> redisTemplate = (RedisTemplate<Object, Object>) context.getBean("redisTemplate");
redisTemplate.convertAndSend("test", "123");
}
Run Code Online (Sandbox Code Playgroud)
我得到以下stacktrace:
java.lang.ExceptionInInitializerError
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:252)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:58)
at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:128)
at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:91)
at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:78)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:178)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:153)
at org.springframework.data.redis.core.RedisTemplate.convertAndSend(RedisTemplate.java:676)
at com.jobvite.realtimeanalytics.redis.RedisTest.testRedis(RedisTest.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) …Run Code Online (Sandbox Code Playgroud) 我注意到存储在Redis中的一些序列化对象在反序列化方面存在问题.
当我对存储在Redis中的对象类进行更改时,通常会发生这种情况.
我想了解这个问题,以便为解决方案设计一个清晰的设计.
我的问题是,导致反序列化问题的原因是什么?拆除公共/私人财产会导致问题吗?或许可以添加新属性?为类添加新函数会产生问题吗?更多的构造函数呢?
在我的序列化对象中,我有一个属性Map,如果我更改(更新了一些属性,添加了函数等)myObject,它会导致反序列化问题吗?
serializable redis deserialization spring-data spring-data-redis
嘿所有,我们有Spring使用的项目Spring security.我们通过定义来定义安全过滤器
<b:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
Run Code Online (Sandbox Code Playgroud)
蒙山 filter-chain-map
在web.xml我们这样做
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)
这一切都很好:).现在挂钩时,Spring session与redis根据doc 下届行
<context:annotation-config />
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>
Run Code Online (Sandbox Code Playgroud)
创建一个filter命名springSessionRepositoryFilter.基本上我们所做的就是在每个自定义中filter-chain我们添加过滤器作为第一个过滤器.即:
<b:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<filter-chain-map request-matcher="ant">
<filter-chain pattern="/api/someapieformobilelogin" filters="none" /> <!-- no filter on login -->
<filter-chain pattern="/api/**"
filters="springSessionRepositoryFilter, securityContextFilter,and some other spring security filter />
<filter-chain pattern="/**"
filters="springSessionRepositoryFilter, securityContextFilter,and some other spring security filter />
Run Code Online (Sandbox Code Playgroud)
结果 …
正如标题所说,是否有映射到 Redisson 框架的 spring 数据 redis ( http://redisson.org )
我在模拟Redis模板中遇到问题。谁能帮我为下课写单元测试。
@Repository
public class CasheRepo {
@Autowired
private RedisTemplate<String, Object> template;
public Object getObject(final String key) {
return template.opsForValue().get(key);
}
}
Run Code Online (Sandbox Code Playgroud)
下面是单元测试课程。但这不起作用。它显示空点异常
@RunWith(MockitoJUnitRunner.class)
public class CashRepoTest {
@InjectMocks
private CasheRepo casheRepo = new CasheRepo();
private @Mock RedisConnection redisConnectionMock;
private @Mock RedisConnectionFactory redisConnectionFactoryMock;
private RedisTemplate redisTemplate;
@Before
public void setUp() { Mockito.when(redisConnectionFactoryMock.getConnection()).thenReturn(redisConnectionMock);
redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(redisConnectionFactoryMock);
redisTemplate.afterPropertiesSet();
}
@Test
public void getObjectTest() {
Mockito.doNothing().when(redisTemplate).opsForValue().set("spring", "data");
redisTemplate.afterPropertiesSet();
System.out.println(redisTemplate.opsForValue().get("spring"));
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试在项目中使用@EnableRedisRepositories和@EnableMapRepositories,但收到以下错误消息:
相关原因:org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为“redisConverter”的bean时出错:通过构造函数参数0表示的不满意依赖:无法转换类型[org.springframework.data.keyvalue.core.mapping的参数值。 context.KeyValueMappingContext] 到所需类型 [org.springframework.data.redis.core.mapping.RedisMappingContext]:无法将类型“org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext”的值转换为所需类型“ org.springframework.data.redis.core.mapping.RedisMappingContext'; 嵌套异常是 java.lang.IllegalStateException:无法将“org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext”类型的值转换为所需类型“org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext”。
那么是否可以在同一个项目中同时使用两者?
将以下所示的2个依赖项添加到我的应用程序后,一切正常,我的会话数据被写入到本地Redis服务器,但是当我尝试指定其他Redis服务器地址时,出现错误。我认为该错误与某些依赖性问题有关,但是我不知道如何解决此问题。
compile "org.springframework.boot:spring-boot-starter-data-redis-reactive:${springVersion}"
compile "org.springframework.session:spring-session-data-redis:${springVersion}"
Run Code Online (Sandbox Code Playgroud)
启动时出错
java.lang.IllegalStateException:org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:64)上的org.springframework.boot.auto.config.context.PropertyPlaceholderAutoConfiguration.propertySourcesPlaceholderConfigurer上的错误处理条件autoconfigure-2.0.2.RELEASE.jar:2.0.2.RELEASE],位于org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108)〜[spring-context-5.0.6.RELEASE.jar:5.0 .6.RELEASE]在org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:180)〜[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]在org.springframework.context .annotation.ConfigurationClassBeanDefinitionReader。loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:141)〜[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]在org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117)〜[spring -context-5.0.6.RELEASE.jar:5.0.6.RELEASE],位于org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:328)〜[spring-context-5.0.6.RELEASE.jar: 5.0.6.RELEASE],位于org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:233)〜[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]。 context.support.PostProcessorRegistrationDelegate。invokeorgDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:273)〜[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]在org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:93)〜[spring -context-5.0.6.RELEASE.jar:5.0.6.RELEASE],位于org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694)〜[spring-context-5.0.6.RELEASE.jar:在org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)〜[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]中的[5.0.6.RELEASE]。 boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:61)〜[spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]在org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)[spring-boot-2.0.2.RELEASE。 jar:2.0.2.RELEASE]位于org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395)[spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]位于org.springframework.boot .org.springApplication.run(SpringApplication.java:327)[spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]在org.springframework.boot.SpringApplication.run(SpringApplication.java:1255)[spring-在org.springframework.boot.SpringApplication.run(SpringApplication.java:1243)的boot-2.0.2.RELEASE.jar:2.0.2.RELEASE] [spring-boot-2.0.2.RELEASE.jar:2.0.2。释放],位于pl.bk.pizza.store.Initializer.main(Initializer.java:11)[classes /:na]原因:java.lang.IllegalStateException:无法在org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:659)上从ClassLoader [sun.misc.Launcher$AppClassLoader@18b4aac2]自检类[org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration] )〜[spring-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]在org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:556)〜[spring-core-5.0.6.RELEASE。 jar:5.0.6.RELEASE]在org.springframework.org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:569)〜[spring-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]。 util.ReflectionUtils.doWithMethods(ReflectionUtils.java:541)〜[spring-core-5.0.6.RELEASE.jar:5.0.6.RELEASE]在org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:599)〜 [spring-core-5.0.6。RELEASE.jar:5.0.6.RELEASE],位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:724)〜[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE ]在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:665)〜[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]在org.springframework.beans.factory .support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:633)〜[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]在org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory。 java:1489)〜[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE],网址为org.springframework.beans.factory.support.AbstractBeanFactory。isFactoryBean(AbstractBeanFactory.java:1012)〜[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]在org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.addBeanTypeForNonAliasDefinition(BeanTypeRegistry.java:164)〜 org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.addBeanType(BeanTypeRegistry.java:153)上的[spring-boot-autoconfigure-2.0.2.RELEASE.jar:2.0.2.RELEASE]〜[spring-boot-autoconfigure- 2.0.2.RELEASE.jar:2.0.2.RELEASE],位于org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.updateTypesIfNecessary(BeanTypeRegistry.java:203)〜[spring-boot-autoconfigure-2.0.2.RELEASE.jar :2.0.2.RELEASE],位于org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.getNamesForType(BeanTypeRegistry.java:115)〜[spring-boot-autoconfigure-2.0.2.RELEASE.jar:2.0.2.RELEASE]在org.springframework.boot。autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:265)〜[spring-boot-autoconfigure-2.0.2.RELEASE.jar:2.0.2.RELEASE] at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType (OnBeanCondition.java:254)〜[spring-boot-autoconfigure-2.0.2.RELEASE.jar:2.0.2.RELEASE]在org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:196) 〜[spring-boot-autoconfigure-2.0.2.RELEASE.jar:2.0.2.RELEASE]在org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:116)〜[spring-boot-autoconfigure -2.0.2.RELEASE.jar:2.0.2.RELEASE],位于org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)〜[spring-boot-autoconfigure-2.0.2.RELEASE。罐子:2.0.2。[RELEASE] ...省略了17个公共框架造成原因:java.lang.NoClassDefFoundError:java.lang.ClassLoader.defineClass1(本机方法)处的javax / servlet / Filter(java.lang处的[na:1.8.0-internal])。 ClassLoader.defineClass(ClassLoader.java:763)〜[na:1.8.0-内部] at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)〜[na:1.8.0-内部] at java.net。 URLClassLoader.defineClass(URLClassLoader.java:467)〜[na:1.8.0-内部] at java.net.URLClassLoader.access $ 100(URLClassLoader.java:73)〜[na:1.8.0-内部] at java.net .URLClassLoader $ 1.run(URLClassLoader.java:368)〜[na:1.8.0-internal] at java.net.URLClassLoader $ 1.run(URLClassLoader.java:362)〜[na:1.8.0-internal] at java .security.AccessController.doPrivileged(本机方法)〜[na:1.8.0-internal] at java.net.URLClassLoader.findClass(URLClassLoader。java:361)〜[na:1.8.0-internal] at java.lang.ClassLoader.loadClass(ClassLoader.java:424)〜[na:1.8.0-internal] at sun.misc.Launcher $ AppClassLoader.loadClass( Launcher.java:331)〜[na:1.8.0-内部]在java.lang.ClassLoader.loadClass(ClassLoader.java:357)〜[na:1.8.0-内部]在java.lang.ClassLoader.defineClass1(本机方法)〜[na:1.8.0-内部] at java.lang.ClassLoader.defineClass(ClassLoader.java:763)〜[na:1.8.0-内部] at java.security.SecureClassLoader.defineClass(SecureClassLoader.java :142)〜[na:1.8.0-internal] at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)〜[na:1.8.0-internal] at java.net.URLClassLoader.access $ …
我在使用 JAVA 11 的日志文件中以红线显示以下内容。
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.util.ReflectionUtils (file:/C:/Users/lol/.m2/repository/org/springframework/spring-core/5.1.5.RELEASE/spring-core-5.1.5.RELEASE.jar) to constructor java.math.BigDecimal(java.math.BigInteger,long,int,int)
WARNING: Please consider reporting this to the maintainers of org.springframework.util.ReflectionUtils
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Run Code Online (Sandbox Code Playgroud)
我也得到以下信息。这是否意味着 spring-data-redis 有问题
java.lang.UnsupportedOperationException: Reflective setAccessible(true) disabled
at io.netty.util.internal.ReflectionUtil.trySetAccessible(ReflectionUtil.java:31)
at io.netty.util.internal.PlatformDependent0$4.run(PlatformDependent0.java:224)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at io.netty.util.internal.PlatformDependent0.<clinit>(PlatformDependent0.java:218)
at io.netty.util.internal.PlatformDependent.isAndroid(PlatformDependent.java:212)
at io.netty.util.internal.PlatformDependent.<clinit>(PlatformDependent.java:80)
at io.netty.util.ResourceLeakDetector.<init>(ResourceLeakDetector.java:171)
at io.netty.util.ResourceLeakDetector.<init>(ResourceLeakDetector.java:213) …Run Code Online (Sandbox Code Playgroud) 有没有办法防止spring-boot应用程序因外部连接失败而启动失败?我发现其他类似的问题建议使用@Lazy注释来防止bean 初始化,但此解决方案对我使用客户端@Configuration不起作用。Spring Data RedisJedis
此外,像这样的其他解决方案特定于应用程序中使用的依赖项。例如,Spring Cloud具有以下属性来控制快速失败行为 -
spring.cloud.config.fail-fast=true
Run Code Online (Sandbox Code Playgroud)
您可以使用我为我的问题创建的这个项目,通过关闭redis服务器来重现。
下面是我的代码的样子 -
@Lazy
@Configuration
public class RedisConfiguration {
@Value("${spring.redis.sentinel.master}")
private String SENTINEL_MASTER;
@Value("${spring.redis.sentinel.nodes}")
private String SENTINEL_NODES;
@Value("${spring.redis.security.enabled:false}")
private boolean REDIS_SECURITY_ENABLED;
@Value("${spring.redis.security.password:}")
private String REDIS_PASSWORD;
@Lazy
@Bean // somehow this always gets initialized
public RedisConnectionFactory jedisConnectionFactory() {
// create set of sentinel nodes
System.out.println(SENTINEL_NODES);
Set<String> sentinelNodesSet = new HashSet<>(5);
StringTokenizer st = new StringTokenizer(SENTINEL_NODES, …Run Code Online (Sandbox Code Playgroud) 我正在使用 Spring Session Redis Data(使用自动配置进行配置,到目前为止没有自定义),它默认用作FindByIndexNameSessionRepository实现SessionRepository。
但是,有时在 Redis 中(在会话已过期但未执行注销之后),前缀为 的密钥的spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:TTL 仍为 -1,这意味着 Redis 不会使该密钥过期。
为什么 Spring Session(Redis 数据)在会话过期时不清理这个键?我在文档中也找不到提及。
我已按照文档中所述将带有主体名称的属性存储到会话中,但这并不能解决此问题。有关详细信息,请参阅https://docs.spring.io/spring-session/reference/api.html#api-findbyindexnamesessionrepository。
使用的Redis版本:6.2.6(bitnami/redis的docker镜像:6.2.6)
相关依赖:
我不希望索引持久化的原因是,如果有很多用户至少登录过一次并且有一个密钥持久化到Redis(其作用类似于索引),那么Redis将不得不存储可能无法访问的数据很长一段时间(或根本没有)。
spring-security spring-data-redis spring-boot spring-session
spring-boot ×4
spring ×3
spring-data ×3
java ×2
redis ×2
mockito ×1
netty ×1
redisson ×1
serializable ×1
unit-testing ×1